前言
最近在看《深入理解Java虚拟机》一书,看到了类初始化的五种情况。联想到之前看到过通过静态内部类来实现单例懒加载的模式,当时不理解其原理,现在特此记录一下。
由传统单例引起
传统的单例模式分为饿汉,懒汉模式。因为synchronized 关键字,导致性能被浪费。在实例化之后的对象读取,希望是无锁的。所以引入“双检锁模式”
public class Singleton{
private static Singleton singleton;
private Singleton() {
}
public synchronized static Single newInstance() {
if (singleton== null) {
singleton= new Singleton();
}
return singleton;
}
}
双检锁
但是,这种双检锁模式也会存在问题,多线程情况下,会出现某个线程获取到的实例对象虽然被赋予默认值,但其初始化还未完成的情况。这种问题的解决办法则是添加volatile关键字,但volatile也会有性能损耗。
public class DoubleCheckedLock {
private static DoubleCheckedLock instance;
public static DoubleCheckedLock getInstance(){
if (null == instance){
synchronized (DoubleCheckedLock.class){