Dom*_*ino 0 java multithreading deadlock
对于我的编程语言类,我们已经获得了一个简单的Java死锁示例,并被要求解决它.我不直接想要这个问题的答案,我主要想知道我的理解缺乏的地方.这是代码:
import java.applet.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Attempt at a simple handshake. Girl pings Boy, gets confirmation.
// Then Boy pings girl, get confirmation.
class Monitor {
String name;
public Monitor (String name) { this.name = name; }
public String getName() { return this.name; }
// Girl thread invokes ping, asks Boy to confirm. But Boy invokes ping,
// and asks Girl to confirm. Neither Boy nor Girl can give time to their
// confirm call because they are stuck in ping. Hence the handshake
// cannot be completed.
public synchronized void ping (Monitor p) {
System.out.println(this.name + " (ping): pinging " + p.getName());
p.confirm(this);
System.out.println(this.name + " (ping): got confirmation");
}
public synchronized void confirm (Monitor p) {
System.out.println(this.name+" (confirm): confirm to "+p.getName());
}
}
class Runner extends Thread {
Monitor m1, m2;
public Runner (Monitor m1, Monitor m2) {
this.m1 = m1;
this.m2 = m2;
}
public void run () {
//System.out.println(m1.getName() + " about to ping " + m2.getName());
m1.ping(m2);
}
}
public class DeadLock {
public static void main (String args[]) {
int i=1;
System.out.println("Starting..."+(i++));
Monitor a = new Monitor("Girl");
Monitor b = new Monitor("Boy");
(new Runner(a, b)).start();
(new Runner(b, a)).start();
}
}
Run Code Online (Sandbox Code Playgroud)
当我执行上面的代码时,我相信每次都会发生以下情况(虽然它没有,因为有时我们会死锁):
女孩ping男孩,把锁放在ping()方法上.女孩,里面ping(),试图打电话boy.confirm().男孩的confirm()答案,因此把我们带回到Girl.ping()它完成的地方,取消了锁定ping(),而Boy的实例完全相同.使用所有锁定,似乎整个程序被序列化,从而破坏了多线程的目的?无论如何,我通常会得到以下输出
Starting...1
Girl (ping): pinging Boy
Boy (confirm): confirm to Girl
Girl (ping): got confirmation
Boy (ping): pinging Girl
Girl (confirm): confirm to Boy
Boy (ping): got confirmation
Run Code Online (Sandbox Code Playgroud)
但是有时我们会遇到死锁,输出变为:
Girl (ping): pinging Boy
Boy (ping): pinging Girl
Run Code Online (Sandbox Code Playgroud)
我不明白我们怎么能进入这种状态,因为看起来ping()我们第一次进去的时候就锁定了这个方法,所以ping()如果女孩已经在使用它,男孩怎么会打电话呢?被女孩试图调用boy.confirm()时,男孩正忙呼ping()?
您的ping方法是同步的,并采取上的锁this,那么它前进到呼叫confirm上p,从而试图夺取其锁定为好.步骤:
Boy对象锁定,进入ping;Girl对象的锁定,进入ping;Boy.confirm,等待锁;Girl.confirm,等待锁;