[英]Java - using wait() and notify()
这不是Java的重复, 带有同步方法的多线程 ...他没有问同样的问题。
我正在尝试编写一个使用多线程和死锁的程序。 我无法理解在同步方法中如何以及在何处使用wait()和notify()来让线程等待并通过notify()将其唤醒。 我让第一个线程在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
我的代码陷入僵局,或者我没有使用wait并正确通知,因为它在这里停止:
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
这是我的代码:
Monitor.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);
}
}
Deadlock.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
,然后等待上a
。
其他线程调用:
(new Runner(b, a)).start();
// which effectively calls in run()
b.ping(a);
这将锁定b
在b
上调用notify,然后在b
上等待。
由于两个线程都没有通知另一个线程,因此它们永远不会离开该状态。 我不确定您要完成什么,因此很难弄清楚如何修复代码。
编辑:
现在,您已经编辑了代码,您将拥有一个更加标准的死锁。
a
然后尝试锁定b
通知它。 b
尝试锁定a
通知它。 每个线程都有其锁,但需要另一个锁才能继续。 经典僵局。
我建议您学习使用调试器@ OhioState22。 设置断点并逐步执行代码。 这是一个不错的Eclipse教程 。
通常,请避免使用Java的wait()和notify(),而是改用Java 5的并发功能之一,例如ReentrantLock。 原因是,如果线程在线程到达wait()之前调用notify(),则后续对wait()的调用将无限期地阻塞,具体取决于您的算法。 在Javadocs中查找RenetrantLock
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.