众所周知,在单例模式中,为了解决多线程造成的创建出多个对象的问题,一般会使用锁机制来强行同步,锁加载方法上浪费性能,于是会lock创建对象的代码块,形如:
lock(obj){
if(instance == null){instance = new Object();}
}
于是就有人提出,2个线程模型下(A和B),A线程取得锁,并创建完对象,释放锁,B线程拿到锁,还要拿到锁,再判断instance==null,浪费性能,于是就改造出了双重锁定的东西,形如:
if(instance == null){
lock(obj){
if(instance == null){instance = new Object();}
}
}
我想问:
A线程拿到锁之后,还没来得及判断instance==null,CPU的控制权就被B线程获得,然后B线程等待A线程释放锁,A线程继续创建instance,然后B线程还不是会继续取得锁,判断null,这个双重锁定有个什么用?
请高人指点一二!不胜感激!
第一个判断null是为了尽量减少进入锁的线程数;
第二个判断null是为了防止进入锁只有的多个线程重复创建实例;
回答的很简洁明白,谢谢
是在不为空的时候系统就不会出现锁,而且不为空的情况是最多的
1、A线程和B线程获取instance,此时如果instance为空,假设A线程先拿到锁,然后判断instance为空,则创建一个对象,接着释放锁;紧接着B拿到锁,此时判断instance为空不成立,直接释放锁并返回,明显少创建了一次对象。Double Check的目的是在临界状态下少创建对象。
2、经过步骤1,instance不为空,外面的那个判断if(instance == null)不成立,直接返回instance,可以减少锁定,提高性能
懂了,第一层if是为了减少锁定
多线程中对同一个对象,在加锁之前的所有判定都是不靠谱的。因为加锁之前别的线程可以对这个对象做任何事情。