如果我绘制了一个图表来表示对阻塞函数(java 同步方法)的所有可能调用,并且我在这个图表中没有任何循环,我可以确定死锁是不可能的。petri-nets 不是这样工作的吗?
我不是在寻找这样的答案:使用一些怪物框架等等。
我想用同步方法处理我的多线程。
EDIT1:尖箭头表示一个类是否调用另一个类的任何同步方法 EDIT2:klick @here 示例,显示一个循环
如果我绘制了一个图表来表示对阻塞函数(java 同步方法)的所有可能调用,并且我在这个图表中没有任何循环,我可以确定死锁是不可能的。petri-nets 不是这样工作的吗?
我不是在寻找这样的答案:使用一些怪物框架等等。
我想用同步方法处理我的多线程。
EDIT1:尖箭头表示一个类是否调用另一个类的任何同步方法 EDIT2:klick @here 示例,显示一个循环
不,这还不够。假设您必须线程:A 和 B。A 调用对象 o1 的方法 m1,该方法调用对象 o2 的方法 m1。线程 B 调用对象 o2 的方法 m2,它调用对象 o1 的方法 m2。假设所有方法都是同步的。现在,A 和 B 的并发执行会导致死锁。虽然,方法之间没有循环调用关系。
那是家庭作业吗?
即使您对类进行了编辑,这还不够,因为您可以通过非同步方法调用来关闭循环。
synchronized
有些方法可能会在没有关键字的情况下阻塞。例如,这适用于包中的许多方法java.util.concurrent
。您还应该考虑synchronized
方法内部的块。
如果只考虑同步方法,您可能会在方法调用中出现死锁而没有循环,因为同步方法使用对象实例作为监视器。例如,如果您有两个对象 A 和 B,每个对象都有同步方法 1() 和 2()。如果 A.1() 调用 B.1() 和 B.2() 调用 A.2(),虽然方法中没有循环,但如果一个线程B.2()
同时调用另一个调用A.1()
,则存在死锁风险.
不。考虑:
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。对我来说,它很快就会陷入僵局。