JAVA常见的设计模式之单例模式
-
懒汉模式
懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间(搬运工)。
标准的懒汉模式
class LazySingleton {
// 私有成员属性
private LazySingleton lazySingleton;
// 私有构造方法
private LazySingleton() {
}
// 公共的获取实例方法
public LazySingleton getLazySingleton() {
// 如果成员属性为空,则创建实例
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
单线程环境下,该单例模式只会有一个实例
public class TestDemo
{
public static void main(String[] args) {
LazySingleton lazySingleton = LazySingleton.getLazySingleton();
LazySingleton lazySingleton2 = LazySingleton.getLazySingleton();
System.out.println(lazySingleton == lazySingleton2);
}
}
运行结果:
多线程模式下,可能会产生多个实例
public class TestDemo
{
public static void main(String[] args) {
new Thread(() -> {
LazySingleton lazySingleton = LazySingleton.getLazySingleton();
System.out.println(lazySingleton);
}).start();
new Thread(() -> {
LazySingleton lazySingleton = LazySingleton.getLazySingleton();
System.out.println(lazySingleton);
}).start();
}
}
运行结果:
初步改进
class LazySingleton {
// 私有成员属性
private static LazySingleton lazySingleton;
// 私有构造方法
private LazySingleton() {
}
// 公共的获取实例方法
public synchronized static LazySingleton getLazySingleton() {
// 如果成员属性为空,则创建实例
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
缺点,每次调用方法都会加锁,效率低
再次改进
class LazySingleton {
// 私有成员属性,使用volatile可以保证代码的有序性,防止指令重排
private volatile static LazySingleton lazySingleton;
// 私有构造方法
private LazySingleton() {
}
// 公共的获取实例方法
// 使用synchronized + 双重确认机制可以保证线程安全,但有可能存在指令重排,会导致创建多个实例
public static LazySingle