这不是 Java, Multithreading with synchronized methods 的重复项...他没有问同样的问题。
我正在尝试编写一个使用多线程和死锁的程序。我无法理解在同步方法中如何以及在何处使用 wait() 和 notify() 来让线程等待并使用 notification() 唤醒它。我让第一个线程在 ping 语句之后等待,这样下一个线程也将启动它的 ping 语句。但我有一个notify()来唤醒第一个线程,但我不明白为什么该线程不会唤醒。以下应该是我的输出:
Starting...1
Girl (ping): pinging Boy
Boy (ping): pinging Girl
Girl (ping): asking Boy to confirm
Boy (confirm): confirm to Girl
Girl (ping): got confirmation
Boy (ping): asking Girl to confirm
Girl (confirm): confirm to Boy
Boy (ping): got confirmation
我的代码死锁或者我没有正确使用等待和通知,因为它停在这里:
Starting...1
Girl (ping): pinging Boy
Boy (ping): pinging Girl
Girl (ping): asking Boy to confirm
Boy (confirm): confirm to Girl
Girl (ping): got confirmation
这是我的代码:
监视器.java
class Monitor {
String name;
public Monitor (String name) { this.name = name; }
public String getName() { return this.name; }
public synchronized void ping (Monitor p) {
p.release(p);
System.out.println(this.name + " (ping): pinging " + p.getName());
notify();
try { wait(); } catch (Exception e) {}
System.out.println(this.name + " (ping): asking " + p.getName() + " to confirm");
p.confirm(p);
System.out.println(this.name + " (ping): got confirmation");
}
public synchronized void confirm (Monitor p) {
System.out.println(this.name + " (confirm): confirm to " + p.getName());
}
public synchronized void release (Monitor p) {
notify();
}
}
Runner.java
public class Runner extends Thread {
Monitor m1, m2;
public Runner (Monitor m1, Monitor m2) {
this.m1 = m1;
this.m2 = m2;
}
public void run () {
m1.ping(m2);
}
}
死锁.java
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();
}
}
最佳答案
您正在调用:
(new Runner(a, b)).start();
// which effectively calls in run()
a.ping(b);
这会锁定a
,在a
上调用notify,然后等待a
。
其他线程调用:
(new Runner(b, a)).start();
// which effectively calls in run()
b.ping(a);
这会锁定 b
调用 b
上的通知,然后等待 b
。
由于两个线程都没有通知另一个线程,因此它们永远不会离开该状态。我不确定您想要完成什么,因此很难弄清楚如何修复代码。
编辑:
现在您已经编辑了代码,您遇到了更标准的死锁。
- 第一个线程锁定
a
,然后尝试锁定b
以通知它。 - 第二个线程锁定
b
,然后尝试锁定a
以通知它。
每个线程都有自己的锁,但需要另一个锁才能继续。经典的僵局。
我建议你学习使用调试器@OhioState22。设置断点并单步执行代码。这是一个不错的Eclipse tutorial .
关于Java - 使用wait()和notify(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14390257/