Java 设计模式 单例模式
单例模式代码复习
单例模式是常用设计模式之一,本文简单讲解常用的集中Java单例模式实现
1.饿汉式 - 线程安全 (不推荐使用)
2.懒汉式 - 线程非安全 (多线程禁止使用)
3.懒汉式 - 线程安全
4.静态内部类 - 线程安全
5.枚举 - 线程安全 (最佳)
饿汉式 - 线程安全
主要是利用static类型成员变量在类加载-初始化时,由JVM保证了线程安全
思想是空间换时间,Singleton类只要被加载就会导致单例产生
// 单例模式 饿汉式 线程安全
class Singleton {
// 利用Java底层加载类时初始化必保证线程安全特性初始化单例
private static Singleton singleton = new Singleton();
// 私有化构造方法
private Singleton() {}
// 返回单例
public static Singleton getInstance() {
return singleton;
}
}
懒汉式 - 线程非安全 (多线程禁止使用)
不做讲解,不推荐使用
// 单例模式 懒汉式 线程不安全
class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式-双重锁校验 - 线程安全
思想是时间换空间
static单例用volatile修饰是保证多线程代码执行有序性
在instance = new Single()时如果instance没有用volatile修饰,则有可能导致其他代码进入getInstance时判断非空不成立,直接返回instance,而此时instance实际为null
// 单例模式 懒汉式-双重锁校验 线程安全
class Singleton {
// volatile保证创建对象的有序性
private volatile static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
// 双重锁校验
if(instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类-延迟加载 线程安全
当getInstance方法第一次被执行的时候
它第一次读取内部静态类SingletonHelper.instance
此时SingletonHelper类得到初始化
而这个类在装载并被初始化的时候
会初始化它的静态域,从而创建Singleton的实例
由于是静态的域
因此只会在虚拟机装载类的时候初始化一次
并由JVM来保证新车安全
// 单例模式 静态内部类 线程安全
class Singleton {
// 私有化构造方法
private Singleton() {}
// 只有当内部类被使用时才会加载
private static class SingletonHelper {
private static Singleton singleton = new Singleton();
}
public static Singleton getInstance() {
return SingletonHelper.singleton;
}
}
枚举 线程安全
// 单例模式 枚举实现 线程安全
enum Singleton {
INSTANCE;
public void function() {
// TODO
}
}
总结:
以上就是常用的Java单例模式代码实现方式,各有优劣势
比较重要的是需要搞清楚懒汉式-双重锁校验的原理和为何需要使用volatile关键字