双检锁(DCL)的分析

public class Singleton
{
	private static volatile Singleton instance;
	private Singleton() {}
	public static Singleton getInstance()
	{
		if(instance==null)
		{
			synchronized(Singleton.class)
			{
				if(instance==null)
				{
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

1、第二个if(instance==null)判断的原因:

  • 首个线程在进入同步块创建对象的过程中,可能有其他线程通过第一个判断试图进入同步块,此时会被阻塞在同步块队列中;
  • 当首个线程创建完毕后,同步块阻塞队列中的线程会进入同步块,此时instance!=null,防止了对象再创建

2、volatile作用:

在对象创建阶段,对象创建不是原子操作,可以分为:

  1. 在堆中分配对象内存空间

  2. 执行构造方法,初始化对象

  3. 将引用instance指向这个对象的堆内地址

此时2、3步可能发生重排,使instance指向一个未创建完成的对象;此时若有线程要获取instance,则会获取到这个还未创建完成的对象,发生错误

posted @ 2020-12-07 00:30  SNM  阅读(164)  评论(0)    收藏  举报