并发编程
三个核心问题
互斥
无锁
- 不变模式
- 线程本地存储(不共享变量 Thread Local)
- CAS
- Copy-On-Write
- 原子类
互斥锁
- synchronized
Lock
优化读多写少
- ReadWriteLock
- StampedLock
读写锁
协作
- 信号量(Semaphore)
管程(Monitor)
- Lock & Condition
- synchronized
CountDownLatch
- CyclicBarrier
- Phaser
- Exchanger
分工
- Executer 与线程池
- fork/Join
- Future
- Guaraded Suspension 模式
- Balking 模式
- Thread-Per-Message 模式
- 生产者消费者模式
- Worker Thread 模式
- 两阶段终止模式
并发模型
- 共享内存模型
- Actor 模型
- 软件事务内存
- 协程
- CSP 模型
案例
- 高性能限流器 Guava RateLimiter
- 高性能网络应用框架 Netty
- 高性能队列 Disruptor
- 高性能数据库连接池 HikariCP
理论基础
- 死锁分析
- 线程间协作机制
Java 内存模型
不确定性源头
- 可见性
- 有序性
原子性
- 源头是线程切换,比如说 long 型在 32 位机器上读写可能出现诡异的 bug
- 本质是不可分割,解决原子性问题,是要保证中间状态对外不可见
Happens-Before
- 程序的顺序性规则
- volatile 变量规则
- 传递性
- 管程中的锁规则
- 线程 start() 规则
- 线程 join 规则
final
- 避免 "逸出"
synchronized
- 当修饰静态方法的时候,锁定的是当前类的 Class 对象
- 当修饰非静态方法的时候,锁定的是当前实例对象 this
- 受保护资源和锁之间合理的关联关系应该是 N:1
包场:锁要能覆盖所有受保护的资源
- 用当前类的 Class 对象做锁
- 在当前类中添加一个 静态的 Object
不能用 可变对象 做锁
保证可见性
- volatile
- AtomicInteger
- synchronized
写屏障
锁
- 本质是在锁对象的对象头中写入当前线程 id
预防死锁
死锁条件
- 互斥,共享资源 X 和 Y 只能被一个线程占用
占有且等待,线程 T1 已经取得共享资源 X, 在等待共享资源 Y 的时候, 不是放共享资源 X
- 一次性申请资源
不可抢占,其它线程不能强行抢占线程 T1 占有的资源
- 主动释放它所占有的资源
循环等待, 线程 T1 等待线程 T2 所占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待
- 按序申请
观测
- top
- jstack
- java virtualvm
理论基础
字符串
- StringBuffer
- String
- StringBuilder