JRockit使用了一种Lazy-Locking(也叫做Reservation Lock)的技术
-XXlazyUnlocking
我当初是在一个日本IBM实验室的一篇2004年的博士论文上看到的概念,保留锁提出的背景是针对Java Synchronized时候,某个Java对象被1+个线程Aquired Lock的序列通常是某个线程占多的现象,后来发现这是一个普遍现象,可能几乎超过75%的锁争夺都是发生在某个线程上(包括递归锁),从锁获取的序列上看,大部分可能是:
T1 T1 T1 T1 T1 T1 T1 T1 T3 T1 T1 T1 T1 T2 T2 T1 T1 T1 T1
(T1, T2, T3是尝试获取Java Lock)
也就是,针对这种锁现象,JVM设计人员开始采用Lazy-UnLocking的想法,即通过改变锁设计,允许T1获得锁的时候,不需要CAS(Compare and Swap)原子性操作,这也是Lock Reservation(保留给T1)的由来;
而T3需要获取当前Java锁的时候,需要一个代价较为昂贵Cancel T1 Reservation的动作才能获得锁。
Java线程如果没有频繁Contention发生的时候,锁延迟意味着不需要原子性操作便获得对象,大大降低Java Lock在OS上的开销。
Sun也有类似的技术,其实是在JDK 5.0之后便引入
-XX:+UseBiasedLocking
Enables a technique for improving the performance of uncontended synchronization. An object is "biased" toward the thread which first acquires its monitor via a
monitorenter bytecode or synchronized method invocation; subsequent monitor-related operations performed by that thread are relatively much faster on multiprocessor machines. Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled; some applications with certain patterns of locking may see slowdowns, though attempts have been made to minimize the negative impact.
实际上,Sun采用的
UseBiasedLocking是Initail Locker的方式,即第一个获取锁的线程,JVM会为它保留锁(不需要原子性操作),从而,在其后,该线程获取锁等同于uncontended synchronization的效果。
BEA JRockit R27.5提供的lazyUnlocking技术据说可以提升锁性能超过1倍以上,从而简直提高JVM性能达10%以上。
延迟锁(或者保留锁)都是忌讳频繁的多线程竞争锁的情形,比如,如果一个Java对象按照下面的序列被T1,T2,T3线程获取,则保留锁的效果是很差的。
T1,T2, T1, T2, T3, T1, T4, T3, T2......
我个人非常喜欢保留锁,可能是我有所偏见,事实上我接触的公司内部的关于JRockit统计报告,都表明:
1,大量的Java应用不会发生锁竞争
2,Java锁一般都符合保留锁的条件,即大部分情况下,在某个时间片内,都是锁都是被某个线程独占。