深入理解Java虚拟机第三版 第五部分 高效并发
第十二章 Java内存模型与线程
12.3.5 原子性、可见性与有序性
1.原子性
Java内存模型提供了lock和unlock操作满足原子性,但未对用户提供;提供了monitorenter和monitorexit字节码指令来隐式使用这两个操作
synchronized关键字就使用了这两个字节码指令,所以synchronized块之间的操作具备原子性
2.可见性
volatile通过在变量修改后把新值同步回主内存,以及每次使用前立即从主内存刷新来实现可见性
synchronized实现可见性:每次对变量unlock之前,必须把此变量同步到主内存
final实现可见性:被final修饰的字段在构造器中一旦被初始化完成,并且构造器没有把this的引用传递出去,那么在其他线程就能看见final字段的值
3.有序性
volatile本身包含了禁止指令重排的语义
synchronized通过“一个变量在同一时刻只允许一条线程对其进行lock操作”实现有序性
12.4.3 线程状态转换
第十三章 线程安全与锁优化
13.2.2 线程安全的实现方法
1.互斥同步
synchronized:持有锁,重量级锁
java.util.concurrent.locks.Lock:重入锁,ReentrantLock和synchronized相似,多了三个高级功能:
等待可中断:当持有锁的线程长期不释放锁,等待线程可以放弃等待
公平锁:通过boolean参数可以使用公平锁,但效率很低
锁绑定多个条件:
2.非阻塞同步
类似乐观锁
CAS:无限循环for(;;)
3.无同步方案
13.3 锁优化
1.自旋锁与自适应锁
2.锁消除
3.锁粗化
4.轻量级锁
5.偏向锁:第一个线程获取锁之后,如果没有其他线程来获取锁,则这个线程永远不需要再同步;一旦别的线程尝试获取锁,偏向模式立刻结束