本文最后更新于:2024年4月22日 下午
安全发布对象,讲述在编码中我们对公共资源正确发布来保证线程安全,且简述使用几种单例模式来发布对象
概念
发布对象:是一个对象能够被当前范围之外的代码嗦使用
对象溢出:一种错误的发布。当一个对象还没有构造完成时,就使它被其它线程所见
四种安全的发布对象
- 在静态初始化函数中初始化一个对象引用 (JVM 在静态初始化的时候会保证线程安全)
- 将对象的引用保存到 volatile 类型的域或者 AtomicReferance 中
- 将对象的引用保存到某个正确构造对象的的 final 类型域中
- 将对象的引用保存到一个由锁保护的域中
线程安全的单例模式的写法
饿汉式(类加载的时候就创建好)
备注:饿汉模式还可以通过静态块来初始化,需要注意静态域和静态代码块的顺序(决定先加载对象还是先加载静态代码块初始对象,如果静态代码块在前就会出现空指针),这里就不演示了
懒汉式(需要的时候才去创建)【不推荐的写法】
懒汉式(需要的时候才去创建)-【推荐的写法】
为什么需要使用volatile
// instance = new SingletonExample3();
cpu的指令,执行new对象的时候分为三步
- memory=allocate() 分配对象内存空间
- ctorInstance() 初始化对象
- instance=memory 设置instance指向刚分配的内存
多线程情况下会出问题
JVM和CPU 发生指令重排 变成1 3 2,因为3和2的顺序不重要
解决办法:使用volatile 禁止指令重排
枚举模式:最安全