饿汉式实现
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
懒汉式实现(线程不安全版本)
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
懒汉式实现(线程安全版本,使用 synchronized 关键字)
public class ThreadSafeLazySingleton {
private static ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton() {}
public static synchronized ThreadSafeLazySingleton getInstance() {
if (instance == null) {
instance = new ThreadSafeLazySingleton();
}
return instance;
}
}
实现原理区别
- 饿汉式:在类加载时就立即创建实例,不管是否需要使用该实例。
- 懒汉式:只有在第一次调用
getInstance
方法时才创建实例。
线程安全性区别
- 饿汉式:天生线程安全,因为实例在类加载时就创建好了,不存在多线程同时创建实例的问题。
- 懒汉式:普通懒汉式实现线程不安全,因为在多线程环境下,可能会有多个线程同时判断
instance == null
为真,从而创建多个实例。线程安全版本的懒汉式通过 synchronized
关键字保证同一时间只有一个线程可以进入 getInstance
方法创建实例。
应用场景区别
- 饿汉式:适用于实例创建开销不大,且应用程序启动后很快就会使用该实例的场景,或者要求绝对线程安全的场景。
- 懒汉式:适用于实例创建开销较大,且在应用程序启动初期不需要立即使用该实例的场景,以节省内存资源。线程安全版本懒汉式虽然保证了线程安全,但由于
synchronized
关键字的存在,性能会有所损耗,在高并发场景下使用需要权衡。