1、可见性
1.1 失效数据
不同步,可能读取到失效值。
@NotThreadSafe
public class MutableInteger {
private int value;
public int get() {return value;}
public void set(int value) {this.value = value;}
}
1.2 不安全的64位操作
- 多线程中使用共享且可变的long和double等类型的变量也是不安全的。
1.3 加锁与可见性
- happens-before
- 确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。
1.4 volatile变量
- volatile变量不会被缓存在寄存器或者其他处理器不可见的地方
- volatile语义不足以确保递增操作的原子性
2、发布与逸出
- 发布一个对象是指使对象能够在当前作用域之外的代码中使用。
- 不要在构造过程中使this引用逸出。
https://blog.csdn.net/zhangwei_david/article/details/84683407
3、线程封闭
- 一种避免使用同步的方式就是不共享数据。
3.2 栈封闭
局部变量
3.3 ThreadLocal
- ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享。
- ThreadLocal提供get set为每个使用该变量的线程都存有一份独立副本。
4、不变性
- 不可变对象一定是安全的
- 不可变的对象和不可变的对象引用之间存在着差异
4.1 Final域
- final域能确保初始化过程的安全性。
- 除非需要更高的可见性,否则应将所有的域都声明为私有域。
5、安全发布
5.3 安全发布的常用模式
- 静态初始化函数中初始化一个对象引用
- 对象引用保存到volatile类型域
- 对象引用保存到某个正确构造对象的final类型域
- 讲对象引用保存到一个由所保护的域
5.6 安全地共享对象
- 线程封闭。
- 只读共享。
- 线程安全共享。
- 保护对象。只能通过持有特定锁来访问。