从单例模式的Double-Check看指令重排

Posted 彭薄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从单例模式的Double-Check看指令重排相关的知识,希望对你有一定的参考价值。

  晚上同学问了我一个问题,单例模式的Double-Check机制在多线程模式是否会出现问题。这个问题我当时有些琢磨不透,晚上翻阅书籍记录一下这个问题的收获。

 

public class Singleton 
	public static Singleton instance;
	
	private Singleton();
	
	public static Singleton getInstance()
		if(instance==null)
			synchronized (Singleton.class) 
				if(instance==null)
					instance=new Singleton();
				
			
		
		return instance;
	
  其中的关键在于,初始化和赋值操作是分开的。在多线程情况下,由于CPU考虑到提高自身利用率,会进行指令的重排。导致的结果是,可能会出现下面这种危险的情况:

  第一步:现在堆上开辟空间

  第二步:把刚刚开辟的地址空间赋值给instance栈变量

  第三步:初始化对象。

假如在第二步的时候,另外的线程判断instance不为null,直接调用就会出现错误。

  

以上是关于从单例模式的Double-Check看指令重排的主要内容,如果未能解决你的问题,请参考以下文章

从单例谈double-check必要性,多种单例各取所需

从单例谈double-check必要性,多种单例各取所需

从单例谈double-check必要性,多种单例各取所需

static实现单例的隐患

你的单例模式真的安全吗?双重检索模式和指令重排序助你高垒单例安全防御

从单例模式看Vue单例组件