不安全的单例
/** * 不安全的单例.<br> * @author gqltt<br> * @version 1.0.0 2020年4月7日<br> * @see * @since JDK 1.5.0 */ public class Singleton { // volatile 修饰保证安全. private static Singleton instance = null; public static Singleton getInstance() { // 如果线程A在执行2后切换,线程B进来---bug if(null == instance) { synchronized (Singleton.class) { if(null == instance) { // new的顺序指令可能导致bug //1、初始化一块内存M //2、instance指向内存&M //3、创建对象 instance = new Singleton(); } } } return instance; } }
new 顺序
问题
出在 new 操作上,我们以为的 new 操作应该是:
1、分配一块内存 M;
2、在内存 M 上初始化 Singleton 对象;
3、然后 M 的地址赋值给 instance 变量。
但是实际上优化后的执行路径却是这样的:
1、分配一块内存 M;
2、将 M 的地址赋值给 instance 变量;
3、最后在内存 M 上初始化 Singleton 对象。
解决
instance改为volatile或者final