0

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

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

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

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

4

3 回答 3

2

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

那是家庭作业吗?

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

于 2011-04-01T10:27:09.120 回答
0

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

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

于 2011-04-01T09:44:06.407 回答
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。对我来说,它很快就会陷入僵局。

于 2011-04-01T10:27:51.787 回答