本文中所提及的锁指的均是 JVM 提供的 synchronized.
在并发编程中,synchronized 一直被称为重量级锁,但是随着 JDK1.6 对 synchronized 进行了各种优化之后,有些情况下它就并不那么重了。本文将介绍从 JDK1.6 开始引入的以下三种锁优化手段。
- 自适应自旋锁(Adaptive Spining)
- 锁消除(Lock Eliminate)
- 锁粗化(Lock Cosarening)
自旋锁与自适应自旋锁
1. 自旋锁
互斥同步进入阻塞状态的开销都很大,应该尽量避免。大多数情况下,共享数据的锁定状态持续时间很短。自旋锁的思想是让一个线程在请求一个共享数据的锁时执行忙循环(自旋)一段时间,不让出 CPU,如果在这段时间内能获得锁,就可以避免进入阻塞状态。
但是,很容易想象到这种情况,如果锁会被线程占用很长时间,那么进行忙循环操作占用 CPU 时间就会造成很大的性能开销,所以自旋锁只适用于共享数据的锁定状态很短的场景。
2. 自适应自旋锁
在 JDK 1.6 中引入了自适应的自旋锁。自适应意味着自旋的次数不再固定了,而是由前一次在同一个锁上的自旋次数及锁的拥有者的状态来决定。
锁消除
锁消除是一种更为彻底的优化,在 JIT 编译时,对运行上下文进行扫描,去除不可能存在共享资源竞争的锁。
public void add(String str1,String str2){
StringBuffer sb = new StringBuffer()