在此代码示例中,Java中的重新进入使我们免于陷入僵局..为什么,为什么? [英] Re-entrancy in Java saves us from a deadlock situation in this code sample.. How, why?

查看:71
本文介绍了在此代码示例中,Java中的重新进入使我们免于陷入僵局..为什么,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java和OOP的新手.我正在用Java阅读并发性,在第2章中,它讨论了可重入性.我不太了解如何发生僵局.有人可以打破这种情况,让我逐步了解细节吗?

I'm new to Java and OOP. I'm reading concurrency in java and in chapter 2, it talks about re-entrancy. I don't quite understand how a deadlock situation would occur. Can some one break this situation down for me to understand the details line by line?

先谢谢您.

如果内部锁未重入,则调用super.doSomething 将永远无法获取锁,因为它将 认为已经暂停,线程将永久停止 等待它永远无法获取的锁.

If intrinsic locks were not reentrant, the call to super.doSomething would never be able to acquire the lock because it would be considered already held, and the thread would permanently stall waiting for a lock it can never acquire.

public class Widget {
    public synchronized void doSomething() {
      ...
    }
}
public class LoggingWidget extends Widget {
   public synchronized void doSomething() {
      System.out.println(toString() + ": calling doSomething");
      super.doSomething();
   }
}

,该线程将永久停止,等待其锁定 无法获得.

and the thread would permanently stall waiting for a lock it can never acquire.

为什么,为什么,哪个线程?

How, why, which thread?

推荐答案

为什么,为什么,哪个线程?

How, why, which thread?

死锁的线程是试图获取锁的线程;即这个.

The thread that deadlocks is the thread that attempts to acquire the lock; i.e. this one.

方法:

  1. 获取对LoggingWidget实例的引用

在实例上调用doSomething()

LoggingWidget.doSomething()的调用获得了实例上的锁,因为该方法为synchronized.

The call to LoggingWidget.doSomething() acquires the lock on the instance, since the method is synchronized.

然后,被调用的方法将调用super.doSomething().

The called method then calls super.doSomething().

Widget.doSomething()的调用尝试再次获取实例上的锁,因为超类型方法也是synchronized.

The call to Widget.doSomething() tries to acquire the lock on the instance (again!), since the supertype method is also synchronized.

在步骤5.当前线程尝试在已经锁定的实例上获取原始锁定.如果原始锁不重入,那么将导致死锁...

At step #5. the current thread attempts to acquire a primitive lock on an instance that it has already locked. If primitive locks were not reentrant, then that would deadlock ...

  • 某些线程"已经拥有对象上的锁,因此我们必须等待该线程释放锁,

  • "some thread" already holds the lock on the object, so we have to wait for that thread to release the lock,

某个线程"是当前线程...并且直到我们从LoggingWidget.doSomething()

that "some thread" is the current thread ... and we are not going to release the lock until we return from the LoggingWidget.doSomething()

但这要等到我们完成对Widget.doSomething()

but that can't happen until after we've completed the call to Widget.doSomething()

这要等到获得锁之后才能发生

and that can't happen until after we've acquired the lock

.....死锁!

但是幸运的是,现实中没有僵局.基本锁是可重入的事实意味着步骤5不需要获取(它已经拥有了),而整个等待我自己去做的事情-无法发生的情况根本不会出现.

But fortunately, there is no deadlock in reality. The fact that primitive locks are reentrant means that step #5 doesn't need to acquire the lock (it already has it), and the whole waiting-for-myself-to-do-something-that-cannot-happen scenario simply does not arise.

为什么:因果关系不可避免的力量:-)

Why: The inescapable power of causality :-)

这篇关于在此代码示例中,Java中的重新进入使我们免于陷入僵局..为什么,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆