| 
                            
                                  一、什么是重量级锁当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁。 
 
 这个重量级锁其实指的就是JVM内部的ObjectMonitor监视器对象: 
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ObjectMonitor() {     _header       = NULL;       //锁对象的原始对象头     _count        = 0;          //抢占当前锁的线程数量     _waiters      = 0,          //调用wait方法后等待的线程数量     _recursions   = 0;          //记录锁重入次数     _object       = NULL;     _owner        = NULL;       //指向持有ObjectMonitor的线程     _WaitSet      = NULL;       //处于wait状态的线程队列,等待被唤醒     _WaitSetLock  = 0 ;     _Responsible  = NULL ;     _succ         = NULL ;     _cxq          = NULL ;     FreeNext      = NULL ;     _EntryList    = NULL ;      //等待锁的线程队列     _SpinFreq     = 0 ;     _SpinClock    = 0 ;     OwnerIsThread = 0 ;     _previous_owner_tid = 0;   } |  二、重量级锁的演示
	
		
			| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class HightweightLockDemo02 {     public static void main(String[] args) {         Object objLock = new Object();         new Thread(() -> {             synchronized (objLock) {                 System.out.println(ClassLayout.parseInstance(objLock).toPrintable());             }         }, "t1").start();         new Thread(() -> {             synchronized (objLock) {                 System.out.println(ClassLayout.parseInstance(objLock).toPrintable());             }         }, "t2").start();     } } |  运行程序: 
java.lang.Object object internals:OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
 0     4        (object header)                           1a 33 c9 e1 (00011010 00110011 11001001 11100001) (-506907878)
 4     4        (object header)                           43 01 00 00 (01000011 00000001 00000000 00000000) (323)
 8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
 12     4        (loss due to the next object alignment)
 Instance size: 16 bytes
 Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
 java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
 0     4        (object header)                           1a 33 c9 e1 (00011010 00110011 11001001 11100001) (-506907878)
 4     4        (object header)                           43 01 00 00 (01000011 00000001 00000000 00000000) (323)
 8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
 12     4        (loss due to the next object alignment)
 Instance size: 16 bytes
 Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
 可见,当多个线程共同抢占同一把锁的时候,锁对象MarkWord的最后三位是“010”,代表的就是一个重量级锁。 三、重量级锁的原理以上述代码为例,synchronized获取的锁是重量级锁,synchronized修饰代码块,使用javap -p -v .\HightweightLockDemo02.class指令查看其字节码: 
 在编译的时候,JVM会在同步块开始位置插入monitorenter指令,在同步块结束位置插入monitorexit指令。当线程执行到monitorenter指令时,会尝试获取对象所对应的Monitor所有权,如果获取成功,则表示获取到了锁,会在Monitor的_owner中存在当前线程的ID,这样它将处于锁定状态,除非退出同步块,否则其他线程无法获取得到这个Monitor。 
 四、锁的优缺点对比下表是对各种状态的锁的对比: 
	
		
			| 锁的类型 | 优点 | 缺点 | 适用场景 |  
			| 偏向锁 | 加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距 | 如果线程间存在锁竞争,会带来额外的锁撤销的消耗 | 适用于只有一个线程访问同步块场景 |  
			| 轻量级锁 | 竞争的线程不会阻塞,提高了程序的响应速度 | 如果始终得不到锁竞争的线程,使用自旋会消耗CPU,导致CPU空转 | 追求响应时间 同步块执行速度非常快 |  
			| 重量级锁 | 线程竞争不使用自旋,不会消耗CPU | 线程阻塞,响应时间缓慢 | 追求吞吐量 同步块执行时间较长 |  
 |