由于您使用的是Thread
,因此下面的代码可能会给出以下结果:
waiting...One waiting...Three waiting...Two Notified...Two Notified...Three
然后代码一直运行,直到它遇到死锁。为什么上面的输出中缺少Notified...One
?需要说明......(多次执行以下代码时,可以得到与上述类似的结果)
class A {
synchronized void waitThread(String threadName) {
System.out.println("waiting..." + threadName);
try {
wait();
} catch(InterruptedException e) { }
System.out.println("Notified..." + threadName);
}
synchronized void notifyThread() {
notifyAll();
}
}
class T1 extends Thread {
A a;
T1(A r, String n) {
a = r;
setName(n);
}
public void run() {
a.waitThread(getName());
}
}
class T2 extends Thread {
A a;
T2(A r, String n) {
a = r;
setName(n);
}
public void run() {
a.notifyThread();
}
}
public class DemoWait {
public static void main(String args[]) {
A a1 = new A();
T1 t1 = new T1(a1,"One");
T1 t2 = new T1(a1,"Two");
T1 t3 = new T1(a1,"Three");
t1.start();
t2.start();
t3.start();
T2 t = new T2(a1,"Four");
t.start();
}
}
答案 0 :(得分:3)
你只是有竞争条件。在t
引用的线程执行notifyAll()
方法之前,变量t1
引用的线程可能会执行waitThread(..)
。这不是僵局。你的一些等待只发生在notifyAll()
之后。
答案 1 :(得分:0)
你正面临Spurious wakeup的问题。那么正在发生的事情是,通知所有其他线程的线程可能会在其他线程之前调用,之后其他线程将运行并等待唤醒。由于虚假唤醒一些线程完成。
更改您的代码......
class A{
boolean flag=true;
synchronized void waitThread(String threadName){
System.out.println("waiting..."+threadName);
try{
while(flag){
wait();
}
}catch(InterruptedException e){ }
System.out.println("Notified..."+threadName);
}
synchronized void notifyThread(){
flag=false;
notifyAll();
} }