java世界的锁原语
1.park/unpark
unpark
public static void unpark(Threadthread)
thread - the thread to unpark, or null, in which case this operation has no effect
park
public static void park(Objectblocker)
Disables the current thread for thread scheduling purposes unless the permit is available.
该原语由posix的条件变量实现
该原语主要用于配合CAS指令实现JUC(Java Util Concurrency)的Lock 和Semaphore,而这些Lock又用于实现JUC里面的各种高级数据结构,效率很高,令人惊叹。
2.对象内置锁
Java世界还有一种更通用的锁是对象内置锁。存储在ObjectHeader中,如下图:
通过字节码我们可以发现,修饰在方法层面的同步关键字,会多一个 ACC_SYNCHRONIZED的flag;修饰在代码块层面的同步块会多一个 monitorenter和 monitorexit关键字。无论采用哪一种方式,本质上都是对一个对象的监视器(monitor)进行获取,而这个获取的过程是排他的,也就是同一个时刻只能有一个线程获得同步块对象的监视器。
在 synchronized的原理分析这篇文章中,有提到对象监视器。
synchronized关键字经过编译之后,会在同步块的前后分别形成monitorenter和monitorexit这两个字节码指令。当我们的JVM把字节码加载到内存的时候,会对这两个指令进行解析。这两个字节码都需要一个Object类型的参数来指明要锁定和解锁的对象。如果Java程序中的synchronized明确指定了对象参数,那么这个对象就是加锁和解锁的对象;如果没有明确指定,那就根据synchronized修饰的是实例方法还是类方法,获取对应的对象实例或Class对象来作为锁对象
Java1.6以后,对monitorenter关键字进行了优化,出现了偏向锁,轻量级锁,重量级锁,自旋等优化
ObjectMonitor仅代表重量级锁,即会被调度程序调度的锁,JVMTI中的MonitorContendedEnter等函数应该指的是进入了重量级锁的callback函数
网友评论