本文是在学习单例模式时遇到的问题
在多线程中,如何防止单例模式被多次实例,当然是要加锁啦。但是加了锁就意味着线程虽然安全,但效率肯定会变低,这是,就出现了双重检查加锁。但看到这段代码,我又有疑问了?
public class Singleton { 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; } }
一开始我是看不懂的,为什么会有再次检查实例是否存在呢,上面不是检查了一次了吗?
原来,我忘了,这是在多线程下运行的,当两个线程同时创建实例时,如果没有第二次空判断,那么第一个线程肯定没问题,创建成功,但是当第二个线程也创建时,因为同时执行,它们都可以通过第一重instance == null 的判断。然后由于synchronized,只能进入等待,如果没有第二次判断,第二个线程就可以继续再创建实例了。
单例模式中的懒汉式是和饿汉式
懒汉是和饿汉式区分非常简单,懒汉式,顾名思义,懒加载,在类加载的时候就已经在内部实例化了。饿汉式就相反,等到在用到的时候再加载。