当我们在java中使用synchronized
关键字时,究竟使用了哪个同步原语? Lock, Semaphore, Monitor, Mutex
?
编辑: JVM如何在本机级别实现锁定?
答案 0 :(得分:10)
在字节码级别,java有monitorenter
和monitorexit
操作,记录在this page of The Java Virtual Machine Specification中,下面粘贴了片段( objectref 是操作的操作数,已采取来自堆栈):
每个对象都有一个与之关联的监视器。执行的线程 monitorenter 获得与 objectref 关联的监视器的所有权。如果另一个线程已经拥有与 objectref 关联的监视器,则当前线程将等待直到该对象为止 解锁,然后再次尝试获得所有权。如果是当前线程 已经拥有与 objectref 关联的监视器,它会增加a 监视器中的计数器,指示此线程的次数 进入监视器。如果与 objectref 关联的监视器不是 由任何线程拥有,当前线程成为所有者 监视器,将此监视器的条目数设置为1。
当前线程应该是与之关联的监视器的所有者 objectref 引用的实例。线程减少了 计数器,指示它进入此监视器的次数。如果 结果,计数器的值变为零,即当前线程 释放显示器。如果监视器与 objectref 关联 变得自由,等待获取该监视器的其他线程 被允许尝试这样做。
所以,“监视器”就是答案,在NPE的答案中引用的这个和JLS都没有指明在本机代码级别发生的事情。如果您有一个特定的平台(CPU和操作系统)和一个特定的JVM实现(包括版本),您当然可以查看JVM源(如果它是一个开源JVM),或者在这里询问。
我也遇到了this blog from 1997,其中包含更多细节。
答案 1 :(得分:7)
来自JLS(§17.1. Synchronization):
Java编程语言提供了多种线程间通信机制。这些方法中最基本的是同步,使用监视器实现。 Java中的每个对象都与一个监视器相关联,一个线程可以锁定或解锁。一次只有一个线程可以锁定监视器。尝试锁定该监视器的任何其他线程都将被阻止,直到它们可以获得该监视器上的锁定为止。线程t可以多次锁定特定监视器;每次解锁都会逆转一次锁定操作的效果。
因此,“监视器”是您第一个问题的答案。
关于第二个问题,这是一个未指明的实施细节。