没有循环的死锁

时间:2011-04-01 09:01:42

标签: java synchronization deadlock petri-net

如果我绘制一个符号表示所有可能的阻塞函数调用(java同步方法)的图形,并且我在这个图中没有任何循环,我能确定死锁是不可能的。 petri-net不能那样工作吗?

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

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

EDIT1:指向的箭头表示一个类是否调用另一个类的任何同步方法 EDIT2:klick @示例,显示一个循环

3 个答案:

答案 0 :(得分:2)

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

那是家庭作业吗?

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

答案 1 :(得分:0)

某些方法可能会在没有synchronized关键字的情况下阻止。例如,这适用于包java.util.concurrent中的许多方法。您还应该考虑方法中的synchronized块。

如果只考虑同步方法,则可以在方法调用中没有循环时出现死锁,因为synchronized方法使用对象实例作为监视器。例如,如果你有两个对象A和B,每个对象都有同步方法1()和2()。如果A.1()调用B.1()和B.2()调用A.2(),虽然方法中没有循环,但如果一个线程同时调用B.2(),则另一个调用{ {1}}然后存在死锁风险。

答案 2 :(得分: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。它很快就会陷入僵局。