高效并发是JDK5升级到JDK6之后的一项重要改进。
1、自旋锁与自适应自旋
讨论互斥同步的时候,我们说到了互斥同步里对性能最大的影响就是阻塞,因为会不断地在用户态和内核态之间切换。而假如我们的物理机的CPU是双核及以上的处理器,可以同时让多个线程并行执行,那么我们就可以让后面请求锁的线程“等待一会儿”,但不放弃处理器的执行时间,看看是否有线程释放锁。
为了让线程等待,我们设置一个忙循环(自旋),这就是自旋锁。
自选等待不能代替阻塞,自旋等待本身虽然避免了线程切换的开销,但它是要占用处理器时间的。如果在短时间内另一个线程释放了锁,那么效果就会很好;反之长时间都获取不到锁,那么就会白白浪费CPU的运行时间。
因此,自旋等待必须有一定的限度,如果自旋次数超过了限定的次数仍然没有获取到锁,就应该用传统方式去挂起线程。自旋默认次数是10次,可以使用参数-XX:PreBlockSpin修改。
但对于JDK6来讲,对于自旋锁引入了自适应自旋,于是自旋的次数就不是固定的了。例如对于同一个锁对象,自旋等待刚刚获得过这个锁,并且持有锁的线程正在运行中,那么虚拟机认为这次自旋也很有可能再成功,进而允许自旋相对更长的时间;但对于这个锁自旋很少成功获得锁的话,就可能直接忽略自旋过程,避免浪费处理器资源。
2、锁消除
锁消除是指虚拟机在即时编译器在运行时检测到某段需要同步的代码不可能存在共享数据竞争,而实施对锁进行消除的优化策略。
锁消除的主要判定依据是逃逸分析技术(t