线程安全性
如果当多个线程访问同一个可变的状态变量时没有合适的同步,那么程序就会出现错误。有三种方式可以修复这个问题:
- 不在线程之间共享该状态变量
- 将状态变量修改为不可变的变量
- 在访问状态变量的时候使用同步
当设计线程安全的类的时候,良好的面向对象技术、不可修改性,以及明晰的不变性规范都能起到一定帮助作用
什么是线程安全
当多个线程访问某个类的时候,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么称这个类是线程安全的。
那么如何理解正确性呢?正确性的含义是,某个类的行为与其规范完全一致。在良好的规范中通常会定义各种不变条件来约束对象的状态,以及定义各种后验条件来描述对象的操作结果。
在线程安全的类中封装了必要的同步机制,因此客户端无需进一步采取同步措施。
无状态的对象一定是线程安全的。
原子性
- 竞态条件
当某个计算的正确性取决于多个线程的交替执行顺序时,那么就会发生竞态条件,换句话说,就是正确的结果要取决于运气。最常见的静态条件类型就是“先检查后执行”操作,即通过一个可能失效的观测结果来决定下一步动作。统计命中计数(i++)中存在另一种竞态条件,即“读取-修改-写入”操作
- 复合操作
我们将“先检查后执行”、“读取-修改-写入”等操作统称为复合操作:包含了一组必须以原子方式执行的操作以确保线程的安全性。
加锁机制
- 内置锁
synchronized
- 重入
如果一个线程试图获取已经由它自己持有的锁,这个请求会成功,那么这个锁就是可重入锁。例如内置锁