Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多线程如何获取和释放java中同步方法和同步块中的锁?_Java_Multithreading_Synchronization_Locking - Fatal编程技术网

多线程如何获取和释放java中同步方法和同步块中的锁?

多线程如何获取和释放java中同步方法和同步块中的锁?,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,java线程如何在同步块中使用的监视器或同步方法中使用的监视器上获取锁 我在多篇文章中读到,在有偏锁定的情况下,该信息使用CAS操作存储在对象头中,在竞争情况下,使用等待集队列/监视器队列,但最终仅在对象头中标记锁定。 如果是这种情况,那么锁是如何释放的?另一个线程如何将对象标记为空闲以获取锁?内部是否为此使用了wait和notify方法?如果是这种情况,那么为什么在同步块内使监视器为null不会引发任何异常 下面的示例工作得非常好,我希望NullPointerException假设同步块的末尾

java线程如何在同步块中使用的监视器或同步方法中使用的监视器上获取锁

我在多篇文章中读到,在有偏锁定的情况下,该信息使用CAS操作存储在对象头中,在竞争情况下,使用等待集队列/监视器队列,但最终仅在对象头中标记锁定。 如果是这种情况,那么锁是如何释放的?另一个线程如何将对象标记为空闲以获取锁?内部是否为此使用了wait和notify方法?如果是这种情况,那么为什么在同步块内使监视器为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");

偏锁情况:如果锁偏向某个线程,则不需要CAS;只是一个易变的书写。偏置锁信息保存在对象头的标记字中。偏向锁定将从JDK15中删除

如果锁被争用,对象监视器将用于同步。默认情况下,对象监视器已放气,但如果存在争用或执行等待/通知,则监视器将充气并连接到对象

Linux上的阻塞行为是使用等待队列实现的。因此,当线程需要等待锁定时,它将从调度程序中删除并添加到等待队列中。当锁解锁时,等待队列上的线程将重新插入调度程序

代码不引发异常的原因是,当输入同步块时,监视器只读取一次


PS:可能是由于锁省略,您的锁被完全移除。如果JIT不能提供任何其他线程可以获取该锁,那么同步就没有意义。

请注意,
monitor
是一个变量。它存储对对象的引用。将引用更改为指向
null
将不会删除对象或诸如此类的内容。@akuzminykh如果我的方法长时间运行并触发GC监视器,是否符合收集条件?这会触发NPE吗?更新:所以监视器将不符合GC的条件,因为它仍然被同步构造背后的代码引用@pveentjer的回答更清楚了,如下所示:``Object tmp=monitor;同步输入(tmp);监视器=空;同步退出(tmp)```有什么方法可以验证该对象是只读的吗?我想你理解的文本是错误的。对于同步块,监视器变量仅读取一次(仅读取一次)。请参阅上面的小代码示例。