首先,这是一个示例:
public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void bow(Friend bower) { System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } public synchronized void bowBack(Friend bower) { System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName()); } } public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new Runnable() { public void run() { alphonse.bow(gaston); } }).start(); new Thread(new Runnable() { public void run() { gaston.bow(alphonse); } }).start(); } }
我没有得到的是堵塞如何发生。main函数启动两个线程,每个线程都开始各自的弓箭操作。
“同步”到底阻止了什么?为同一对象运行的功能相同(就像我最初想的那样)?同一类的所有对象具有相同的功能吗?同一对象的所有同步功能?同一类所有对象的所有同步功能?
在Java中,每个函数都Object提供了synchronize在其上锁定或锁定线程的功能。同步方法时,该方法将其对象实例用作锁。在你的示例中,方法bow和bowBack都属于synchronized,并且都位于同一类中Friend。这意味着任何执行这些方法的线程都将在Friend实例上作为其锁进行同步。
Object
synchronize
bow
bowBack
synchronized
Friend
一系列将导致死锁的事件是:
alphonse.bow(gaston)
alphonse
gaston.bow(alphonse)
gaston
bowback
为了更详细地显示事件的顺序:
main()
Therad
new Thread(new Runnable() { ...
alphonse Friend
gaston Friend
bower.bowBack(this)
bower
gaston.bowBack(alphonse)
alphonse.bowBack(gaston)
现在,你处于无法执行任何线程的位置。线程#2和线程#3都在等待释放锁。但是,如果没有Thread进展,则无法释放任何锁定。但是没有释放锁,任何线程都无法取得进展。
因此:死锁!
死锁通常取决于发生的事件的特定顺序,这可能使调试变得困难,因为它们可能难以重现。