java线程如何获取同步块中使用的监视器或同步方法中使用的监视器上的锁?
我在多篇文章中读到,在偏向锁定的情况下,此信息使用CAS操作存储在对象标头中,而在竞争情况下,使用等待设置队列/监视队列,但最终仅在对象标头中标记为锁定。如果是这种情况,那么锁是如何释放的?如何将对象标记为空闲,以便由另一个线程获取锁?wait和notify方法是否在内部使用?如果是这种情况,那么为什么在同步块中使monitor为null不会抛出任何异常。
下面的例子运行得很好,我认为NullPointerException会假设同步块的末尾会尝试标记lock属性来释放锁。
示例:
Object monitor = new Object();
synchronized (monitor){
System.out.println("before null");
monitor =null;
System.out.println("after null");
}
System.out.println("successfully Exited");
发布于 2020-11-04 16:31:03
在偏向锁定的情况下:如果锁定偏向于某个线程,则不需要CAS;只需要易失性写入。偏置的锁信息保存在object头的标记字中。偏向锁定将从JDK 15中删除。
如果存在锁争用,则使用对象监视器进行同步。默认情况下,对象监视器是放气的,但如果存在争用或您执行等待/通知,则监视器会膨胀并附加到对象上。
在Linux上,阻塞行为是使用等待队列实现的。因此,当线程需要等待锁时,它将从调度器中删除并添加到等待队列中。当锁被解锁时,等待队列中的线程被重新插入到调度程序中。
代码没有抛出异常的原因是,当输入synchronized块时,监视器只读取一次。
PS:这可能是你的锁被完全移除,因为锁省略。如果JIT不能提供其他线程可以获得的锁,那么同步就没有意义了。
https://stackoverflow.com/questions/64676327
复制相似问题