什么原语用于实现synchronized关键字?

NIN*_*OOP 8 java multithreading synchronized

当我们synchronized在java中使用关键字时,究竟使用了哪个同步原语?Lock, Semaphore, Monitor, Mutex?

编辑: JVM如何在本机级别实现锁定?

hyd*_*yde 10

在字节码级别,java具有monitorenter和monitorexit操作,在Java虚拟机规范的此页面中记录,下面粘贴了片段(objectref是操作的操作数,取自堆栈):

monitorenter片段

每个对象都有一个与之关联的监视器.执行monitorenter的线程 获得与objectref关联的监视器的所有权.如果另一个线程已经拥有与objectref关联的监视器,则当前线程将等待,直到该对象被解锁,然后再次尝试获得所有权.如果当前线程已经拥有与objectref关联的监视器,它会增加监视器中的计数器,指示此线程进入监视器的次数.如果与objectref关联的监视器不属于任何线程,则当前线程将成为监视器的所有者,并将此监视器的条目数设置为1.

monitorexit片段

当前线程应该是与objectref引用的实例关联的监视器的所有者.线程递减计数器,指示它进入此监视器的次数.如果结果计数器的值变为零,则当前线程释放监视器.如果与objectref关联的监视器 变为空闲,则允许等待获取该监视器的其他线程尝试这样做.

因此,"监视器"就是答案,在NPE的答案中引用的这个和JLS都没有指明在本机代码级别发生的事情.如果您有一个特定的平台(CPU和操作系统)和一个特定的JVM实现(包括版本),您当然可以查看JVM源(如果它是一个开源JVM),或者在这里询问.

我也发生在1997年的这个博客上,其中有更多细节.


NPE*_*NPE 7

来自JLS(§17.1.同步):

Java编程语言为线程之间的通信提供了多种机制.这些方法中最基本的是同步,它是使用监视器实现的.Java中的每个对象都与一个监视器相关联,一个线程可以锁定或解锁.一次只有一个线程可以锁定监视器.尝试锁定该监视器的任何其他线程都将被阻止,直到它们可以获得该监视器上的锁定为止.线程t可以多次锁定特定监视器; 每次解锁都会逆转一次锁定操作的效果.

因此,"监视器"是您第一个问题的答案.

关于第二个问题,这是一个未指明的实现细节.