1. Java 并发机制的底层实现原理
1.1 volatile
1.1.1 定义
定义成volatile的字段,Java线程内存模型确保所有的线程看到这个变量的值是一致的。
1.1.2 实现原理
- Lock 前缀指令会引起处理器缓存写回到地址
- 一个处理器的缓存会写到内存会导致其他处理器的缓存无效。
1.2 synchronized
1.2.1 作用
- 普通的同步方法, 锁住当前实例对象。
- 静态同步方法,锁住当前类的Class对象
- 同步方法块,锁住Synchronized括号里配置的对象。
1.2.2 原理
代码块的同步使用monitorenter(插入到同步代码块之前)和monitorexit(插入到同步代码块之后)指令。任何一个对象对应一个monitor,monitor被持有后会进入锁定状态。线程执行到monitorenter会尝试获取锁。锁存储在Java对象头里面。
1.2.3 锁的升级(不太懂)
1. 偏向锁
锁偏向于已经获得过该锁的线程。
2. 轻量级锁
尝试获取锁,若失败则使用自旋锁。
3. 锁的对比
锁 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
偏向锁 | 一个线程访问同步块 | 快 | 撤销锁耗费资源 |
轻量级锁 | 追求响应时间,同步块执行速度快 | 不阻塞 | 始终得不到锁,自旋会消耗CPU |
重量级锁 | 追求吞吐量,同步块执行时间长 | 不用自旋 | 线程阻塞,响应时间慢 |
1.3 原子操作实现原理
1.3.1 循环CAS
compareAndSet 利用 CMPXCHG指令。若当前值和预期值相等,则set赋值。
面临的问题:
- ABA。 解决思路,增加版本号。
- 循环时间长,开销大。一直在等待compare
- 只能保证一个共享变量。解决思路,把多个变量组合成一个对象。