首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在本代码示例中,Java中的可重入性帮助我们避免了死锁的情况。怎么,为什么?

在本代码示例中,Java中的可重入性帮助我们避免了死锁的情况。怎么,为什么?
EN

Stack Overflow用户
提问于 2014-02-03 02:42:55
回答 2查看 226关注 0票数 1

我对Java和OOP很陌生。我正在阅读java中的并发性,在第2章中,它谈到了可重入性。我不太明白僵局是怎么发生的。有人能打破这种情况,让我一条条地了解细节吗?

提前谢谢你。

如果内部锁不是可重入的,那么对super.doSomething的调用将永远无法获得锁,因为它将被视为已持有,并且线程将永久停止等待它永远无法获得的锁。

代码语言:javascript
复制
public class Widget {
    public synchronized void doSomething() {
      ...
    }
}
public class LoggingWidget extends Widget {
   public synchronized void doSomething() {
      System.out.println(toString() + ": calling doSomething");
      super.doSomething();
   }
}

并且线程将永久停止等待一个它永远无法获得的锁。

怎么,为什么,哪条线?

EN

回答 2

Stack Overflow用户

发布于 2014-02-03 02:48:32

我想你被作者用“重入”这个词弄糊涂了。所谓“锁是可重入的”,他的意思是,如果您的线程已经持有一个锁,则synchronized允许从另一个synchronized方法中输入一个synchronized方法,或者递归地重新输入相同的synchronized方法。

这不同于更常见的可重入性的含义,即当状态保持时,一段代码被重新输入、并发或在同一线程上的能力。

在作者的意思中,如果没有可重入性,synchronized of super.doSomething()将阻止试图获取this.doSomething()持有的锁,因为它们阻塞在同一个对象上(即在this上)。

票数 2
EN

Stack Overflow用户

发布于 2014-02-03 02:55:40

您有两个锁在同一个对象上的方法--一个LoggingWidget实例--将由同一个线程运行。

  1. 创建了一个LoggingWidget实例
  2. 对该实例调用在doSomething类中定义的LoggingWidget方法。
  3. 获得了LoggingWidget实例的一个锁
  4. 执行println语句
  5. doSomething类的LoggingWidget方法调用Widget类中定义的doSomething方法
  6. 需要对同一个LoggingWidget实例进行锁定,但已由执行第一个方法的线程持有它

如果锁不是重入者,则在步骤6时会出现死锁,因为实例上的锁已经被保存。但是,由于在Java中内置的Object锁是可重入的,所以步骤6继续正常,因为所需的锁已经由执行线程持有。

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

https://stackoverflow.com/questions/21518938

复制
相关文章

相似问题

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