先上代码:
1 | public class Singleton { |
为什么是双重校验锁实现单例模式呢?
第一次校验: 也就是第一个 if(singleton==null),由于单例模式只要一次创建实例即可,所以当创建了一个实例之后,再次调用 getInstance 方法就不必要进入同步代码块,不用竞争锁。直接返回前面创建的实例即可。
第二次校验:第个校验是防止二次创建实例,假如有一种情况,当 singleton 还未被创建时,线程 t1 调用 getInstance 方法,由于第一次判断 singleton==null,此时线程 t1 准备继续执行,但是由于资源被线程 t2 抢占了,此时 t2 页调用 getInstance 方法。
同样的,由于 singleton 并没有实例化,t2 同样可以通过第一个 if,然后继续往下执行,同步代码块,第二个 if 也通过,然后 t2 线程创建了一个实例 singleton。
此时 t2 线程完成任务,资源又回到 t1 线程,t1 此时也进入同步代码块,如果没有这个第二个 if,那么,t1 就也会创建一个 singleton 实例,那么,就会出现创建多个实例的情况,但是加上第二个 if,就可以完全避免这个多线程导致多次创建实例的问题。
Others:
- 感觉面试还是紧张了,稍微想一下其实就明白了;