首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在java中,多线程如何获取和释放同步方法和同步块中的锁?

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

Stack Overflow用户
提问于 2020-11-04 16:18:04
回答 1查看 136关注 0票数 2

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

我在多篇文章中读到,在偏向锁定的情况下,此信息使用CAS操作存储在对象标头中,而在竞争情况下,使用等待设置队列/监视队列,但最终仅在对象标头中标记为锁定。如果是这种情况,那么锁是如何释放的?如何将对象标记为空闲,以便由另一个线程获取锁?wait和notify方法是否在内部使用?如果是这种情况,那么为什么在同步块中使monitor为null不会抛出任何异常。

下面的例子运行得很好,我认为NullPointerException会假设同步块的末尾会尝试标记lock属性来释放锁。

示例:

代码语言:javascript
运行
复制
Object monitor = new Object();
    synchronized (monitor){
        System.out.println("before null");
        monitor =null;
        System.out.println("after null");
    }

    System.out.println("successfully Exited");
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-04 16:31:03

在偏向锁定的情况下:如果锁定偏向于某个线程,则不需要CAS;只需要易失性写入。偏置的锁信息保存在object头的标记字中。偏向锁定将从JDK 15中删除。

如果存在锁争用,则使用对象监视器进行同步。默认情况下,对象监视器是放气的,但如果存在争用或您执行等待/通知,则监视器会膨胀并附加到对象上。

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

代码没有抛出异常的原因是,当输入synchronized块时,监视器只读取一次。

PS:这可能是你的锁被完全移除,因为锁省略。如果JIT不能提供其他线程可以获得的锁,那么同步就没有意义了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64676327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档