一、锁优化技术
JDK5之后,在多线程并发上实现了很多锁优化技术,分别是自适应自旋锁、锁消除、锁膨胀、轻量级锁、偏向锁。
二、自适应的自旋锁
自旋锁是其他线程获取持有锁的线程的锁时,让尝试获取锁的线程“忙循环”一会,等待持有锁的线程释放锁。如果,在忙循环结束后,线程依然获取不到锁,线程进入堵塞等待。在JDK4中默认的忙循环次数是10次,当然可以通过编译器参数修改忙循环次数。但是,这样设置自旋锁的忙循环次数是固定的。在JDK6中对自旋锁进行了优化,就是自适应的自旋锁。
自适应的自旋锁是假设上次线程获取锁成功,这次也会成功,自旋锁让线程本次忙循环次数增加。如果,线程上次获取锁失败,线程本次省略忙循环,直接跳过,线程进入堵塞等待,这就是自适应的自旋锁。
虽然,自旋锁让线程忙循环,节省了用户态和内核态的状态切换,忙循环依然占用处理器执行时间。线程短时间的自旋等待后获取锁的效率比线程堵塞等待高效一些,但是,长时间的自旋等待占用处理器执行时间也越多了,效率反而不高了。
三、锁消除
锁消除是指Java虚拟机的即使编译器在运行时,检测需要同步的代码,检测到同步代码的共享数据的锁不存在被竞争,将同步代码的共享数据的锁消除。
四、锁膨胀
在一段代码上,代码分段加锁,需要频繁的加锁和解锁,这样也会有不必要的性能消耗,此时将分段加锁的代码统一加锁一次,减少频繁加锁和解锁。