Java Thread synchronized Deadlock wait(); notifyAll的();

时间:2014-05-24 15:18:47

标签: java multithreading try-catch synchronized

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

2 个答案:

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