Java线程同步死锁notifyAll();



由于您使用的是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();
    }
}

您有一个竞争条件。变量t引用的线程可能在t1引用的线程执行waitThread(..)方法之前执行notifyAll()。这不是僵局。你的一些等待只是发生在你的notifyAll()之后。

您正面临虚假唤醒的问题。那么正在发生的事情是,通知其他所有线程的线程可能会被其他线程提前调用,然后其他线程会运行并等待唤醒。由于虚假唤醒某些线程完成。

修改你的代码…

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();
   }   }

最新更新