java中synchronized方法和synchronized块中多线程如何获取和释放锁?
How does multiple threads acquire and release lock in synchronized methods and synchronized blocks in java?
java 线程如何获取同步块中使用的监视器或同步方法中使用的监视器的锁?
我在多篇文章中读到,在偏向锁定的情况下,此信息使用 CAS 操作存储在 object header 中,在竞争情况下等待设置 queue/ monitor queue 被使用但最终锁定标记在 object header 而已。
如果是这种情况,那么锁是如何释放的呢? object 如何被另一个线程标记为空闲以获取锁?内部使用等待和通知方法吗?如果是这种情况,那么为什么在同步块内使监视器为 null 不会抛出任何异常。
下面的例子工作得很好,我期待 NullPointerException 假设同步块的末尾将尝试标记锁 属性 以释放锁。
示例:
Object monitor = new Object();
synchronized (monitor){
System.out.println("before null");
monitor =null;
System.out.println("after null");
}
System.out.println("successfully Exited");
在偏向锁的情况下:如果锁偏向某个线程,则不需要CAS;只是一个不稳定的写。偏向锁信息保存在对象头的标记字中。偏向锁定将从 JDK 15.
中删除
如果锁被争用,object-monitor 用于同步。默认情况下,对象监视器是放气的,但如果存在争用或您执行 wait/notify,则监视器会膨胀并附加到对象。
On Linux 阻塞行为是使用 wait-queue 实现的。所以当一个线程需要等待一个锁时,它就被从调度器中移除并添加到等待队列中。当锁解锁时,等待队列中的线程被重新插入到调度器中。
之所以代码没有抛出异常,是因为在进入synchronized块时只读了一次monitor
PS: 可能是你的锁因为锁省略而被完全移除。如果 JIT 可以提供没有其他线程可以获取该锁,则同步没有意义。
java 线程如何获取同步块中使用的监视器或同步方法中使用的监视器的锁?
我在多篇文章中读到,在偏向锁定的情况下,此信息使用 CAS 操作存储在 object header 中,在竞争情况下等待设置 queue/ monitor queue 被使用但最终锁定标记在 object header 而已。 如果是这种情况,那么锁是如何释放的呢? object 如何被另一个线程标记为空闲以获取锁?内部使用等待和通知方法吗?如果是这种情况,那么为什么在同步块内使监视器为 null 不会抛出任何异常。
下面的例子工作得很好,我期待 NullPointerException 假设同步块的末尾将尝试标记锁 属性 以释放锁。
示例:
Object monitor = new Object();
synchronized (monitor){
System.out.println("before null");
monitor =null;
System.out.println("after null");
}
System.out.println("successfully Exited");
在偏向锁的情况下:如果锁偏向某个线程,则不需要CAS;只是一个不稳定的写。偏向锁信息保存在对象头的标记字中。偏向锁定将从 JDK 15.
中删除如果锁被争用,object-monitor 用于同步。默认情况下,对象监视器是放气的,但如果存在争用或您执行 wait/notify,则监视器会膨胀并附加到对象。
On Linux 阻塞行为是使用 wait-queue 实现的。所以当一个线程需要等待一个锁时,它就被从调度器中移除并添加到等待队列中。当锁解锁时,等待队列中的线程被重新插入到调度器中。
之所以代码没有抛出异常,是因为在进入synchronized块时只读了一次monitor
PS: 可能是你的锁因为锁省略而被完全移除。如果 JIT 可以提供没有其他线程可以获取该锁,则同步没有意义。