单例模式懒汉和饿汉

版权申明

原创文章:本博所有原创文章,欢迎转载,转载请注明出处,并联系本人取得授权。
版权邮箱地址:[email protected]

单例模式作为最简单的设计模式,在多线程环境下也有一些需要注意的细节

饿汉模式

public class Single {
    
    private static Single instance = new Single();
    
    private Single(){
        
    }
    
    private Single getInstance(){
        return instance;
    }
    
}

这种方式写的单例模式简单实用,最重要的是线程安全,但是缺点就是系统启动实已经实例化了,浪费了系统空间,因此就有了懒汉式的单例模式

public class Single {

    private static Single instance;

    private Single(){

    }

    private Single getInstance(){
        if(instance == null){
            return new Single();
        }
        return instance;
    }

}

这种写法的好处是类可以延迟加载,在需要被使用的时候才会实例化,但是上面的写法在单线程环境没有问题,不过多线程环境下,存在线程安全的问题,因此就有了改进方案,如下:

public class Single {

    private static Single instance;

    private Single(){

    }

    private synchronized Single getInstance(){
        if(instance == null){
            return new Single();
        }
        return instance;
    }


}

上面的代码就比较完善了,不会存在线程安全的问题,也能达到延迟加载的目的,不过直接在方法上面加锁,似乎不是那么完美,每次获取实例的时候都会需要进入串行状态,实在是不太好的体验,并发程度高的话,可能会导致大量线程都在这边等待,因此可以进一步优化代码,如下:

public class Single {

    //volatile 关键词在多线程环境保证变量的每次修改都可以及时被所有其它线程知道
    private static volatile Single instance;

    private Single(){

    }

    private Single getInstance(){
        if(instance == null){
            synchronized (Single.class){
                //双层检查是为了保障如果第一次检查结束后,对象创建前,
                //有其它线程进入了线程同步等待环节,如果没有这一层的检查,则会创建出多个对象
                if(instance == null){
                    return new Single();
                }
            }
        }
        return instance;
    }


}

你可能感兴趣的:(单例模式懒汉和饿汉)