深入理解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 线程状态转换

深入理解Java虚拟机第三版 第五部分 高效并发

 

第十三章 线程安全与锁优化

13.2.2 线程安全的实现方法

1.互斥同步

synchronized:持有锁,重量级锁

java.util.concurrent.locks.Lock:重入锁,ReentrantLock和synchronized相似,多了三个高级功能:

等待可中断:当持有锁的线程长期不释放锁,等待线程可以放弃等待

公平锁:通过boolean参数可以使用公平锁,但效率很低

锁绑定多个条件:

2.非阻塞同步

类似乐观锁

CAS:无限循环for(;;)

3.无同步方案

 

13.3 锁优化

1.自旋锁与自适应锁

2.锁消除

3.锁粗化

4.轻量级锁

5.偏向锁:第一个线程获取锁之后,如果没有其他线程来获取锁,则这个线程永远不需要再同步;一旦别的线程尝试获取锁,偏向模式立刻结束