2011-04-01 92 views
0

如果我绘制一个图形来象征所有可能的调用阻塞函数(java同步方法)并且我没有在这个图中有任何循环,我可以肯定死锁是不可能的。培训网不能像那样工作吗?没有循环的死锁

我不是在寻找像这样的答案:使用一些怪物框架blahblah。

我想用同步方法处理我的多线程。

EDIT1:尖箭头表示如果一个类调用另一个类 EDIT2的任何同步方法:klick @here的例子中,示出了周期没有​​键字

回答

0

号考虑:

private static final Semaphore foo = new Semaphore(1); 
private static final Semaphore bar = new Semaphore(1); 

private static void one() throws InterruptedException { 
    foo.acquire(); 
    bar.acquire(); 
    bar.release(); 
    foo.release(); 
} 

private static void two() throws InterruptedException { 
    bar.acquire(); 
    foo.acquire(); 
    foo.release(); 
    bar.release(); 
} 

为可运行例如参见http://pastebin.com/QfK5ZByj。它对我来说很快就会陷入僵局。

+0

好吧,这很有趣。如果箭头是线条(指向两个方向),那么它将是一个循环。单向箭头不是一个循环。 – 2011-04-01 11:35:54

0

一些方法可能会阻塞。这适用于包java.util.concurrent中的许多方法。您还应该考虑方法内的​​块。

如果仅考虑同步方法,则可以在方法调用中没有循环的情况下产生死锁,因为同步方法将对象实例用作监视器。例如,如果您有两个对象A和B,每个对象具有同步方法1()和2()。如果A.1()调用B.1()和B.2()调用A.2(),虽然方法中没有循环,但如果一个线程同时调用B.2()而另一个调用A.1(),那么有一个僵局风险。

+0

好吧我想我解释错了。如果一个班级另一个班级打电话,我正在谈论绘制一个尖箭头。所以箭头在课堂级别而不是方法级别。但是如果使用同步类,我只考虑绘制箭头。你懂我的意思吗? :-) – 2011-04-01 10:00:58

2

不,这还不够。假设你必须有线程:A和B.调用对象​​o1的方法m1,它调用对象o2的方法m1。线程B调用对象o2的方法m2,该方法调用对象o1的方法m2。假设所有的方法都是同步的。现在,A和B的并发执行会导致死锁。虽然方法之间没有循环调用关系。

是功课吗?

即使您对关于类的编辑还不够,因为您可以通过非同步方法调用来关闭循环。

+0

有趣的是,如果您绘制的是对象而不是方法的图形,则存在一个循环:o1 - > o2 - > o1。这是否适用于所有不涉及等待/通知的死锁情况?尽管如此,这可能不是一种让你在练习中非常有效的方法。 – 2011-04-01 10:30:31

+0

看看我编辑过的picutre,它显示了tom描述的内容。我只在对象级别上讨论连接。我的第一个描述是错误的... – 2011-04-01 11:28:20

+0

@Franz Kafka:看,我的答案的最后一句。 – jmg 2011-04-01 11:34:11