要编写线程安全的代码, 其核心在于要对状态访问操作进行管理, 特别是对共享的 (Shared) 和可变的 (Mutable) 状态的访问.

Java 中的主要同步机制是关键字 synchronized.

其他同步方式:

  • volatile 类型的变量
  • 显式锁 Explicit Lock
  • 原子变量

2.1 什么是线程安全性

在线程安全性的定义中, 最核心的概念是正确性.

image.png

无状态对象一定是线程安全的:

image.png

2.2 原子性

image.png

2.2.1 竞态条件

Race Condition:

  • 正确的结果依赖事件发生的顺序 (时间上的竞争, 时间上的先后)

image.png

最常见的竞态条件就是 “先检查后执行 (Check-Then-Act)” 操作.

2.2.2 示例: 延迟初始化中的竞态条件

“先检查后执行” 的一种常见情况是延迟初始化:

  • 将对象的初始化推迟到被使用时, 同时要确保被初始化一次

image.png

2.2.3 复合操作

线程安全类 AtomicLong:

image.png

2.3 加锁机制