【懒汉模式中的双重检测锁】
记录一下如何理解双重检测中的两次非空判断
直接贴代码⬇
/**
* 懒汉式单例
*/
public class LazyMan {
private LazyMan() {
System.out.println(Thread.currentThread().getName()+"创建了对象");
}
private static volatile LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null){
synchronized (LazyMan.class){
System.out.println(Thread.currentThread().getName()+"进来了");
if (lazyMan ==null){
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
LazyMan.getInstance();
}).start();
}
}
}
可以看到创建实例的getInstance( )方法中使用了两次==null判断以及线程同步锁synchronized,下面根据个人理解做一下简单解释。
锁:控制同一时刻被锁住的代码只能被唯一一个线程访问。
锁外部的空判断:当创建实例方法被调用时候,若该对象不为null,则方法直接结束,不会进入同步代码块,减少执行时间。(因为执行同步代码块中的代码是比较慢的)
锁内部的空判断:在同一时刻,可能会有多个线程进入了锁外部的第一层null判断。当最先进入同步代码块中的线程完成实例创建之后。通过判断阻止其他线程再次进行实例创建。
上面代码运行结果下图:一次进入多个线程,但只会有一个线程会进行创建对象操作。
ps:以上仅仅是个人粗浅理解,如有不当之处敬请指正!同时也希望有更好的理解能够在评论区指教。