我的线程没有得到通知,我的程序挂起

问题描述:

以下代码没有通知线程读取器执行写入器,然后终止。这是为什么? notifyall应唤醒处于等待状态的所有线程。我的线程没有得到通知,我的程序挂起

public class Testing { 

    public static void main(String[] args) { 
     Testing testing=new Testing(); 
     testing.reader.start(); 
     testing.writer.start(); 
    } 
    Thread reader = new Thread("reader") { 
     public void run() { 

      System.out.println("reader started"); 

      synchronized (this) { 
       try { 

        wait(); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
      for (int i = 0; i < 10; i++) { 
       System.out.println("reader " + i); 

      } 
     } 

    }; 
    Thread writer = new Thread("writer") { 
     public void run() { 
      System.out.println("writer started"); 

      for (int i = 0; i < 10; i++) { 
       System.out.println("writer " + i); 
      } 
      synchronized (Thread.currentThread()) { 
       notifyAll(); 
      } 

     } 

    }; 

} 
+0

是返回读线程同时呼吁当前thread.But既不notify和notifyall不会唤醒等待的线程。 –

+0

哎呀!那是一个错误。我会将其改正为作家。事实上,当前返回的线索是作家。您可以帮助我了解如何通知读者线索。 –

+0

如果没有先确认,在'synchronized'块中,不要等待的东西没有发生,就不要调用'wait'。在调用wait后不要确认你正在等待的东西已经发生。 (另外,你的作者调用'notifyAll'而不改变'synchronized'块中的任何内容,所以没有什么可以通知的。) –

notifyAll的()不属于Thread类,但属于对象的基类;在线程作家,notifyAll的()是作家对象的功能,它可以
清醒其具有螺纹作者对象锁; enter image description here

+0

所以我怎么能从writer线程中通知读者线程。 –

以下代码没有通知线程阅读器执行编写器,然后终止。这是为什么?

您的程序没有完成,因为写入程序线程终止,但读卡器线程卡在wait()中。您的代码的问题在于,读者线程正在等待它自己的线程对象,而写入者线程正在通知它自己的线程对象,这是不同的。你需要做的是让他们每个人等待并通知相同的对象实例。

速战速决是使用静态锁定对象:

private static final Object lockObject = new Object(); 
// reader: 
synchronized (lockObject) { 
    lockObject.wait(); 
... 
// writer 
synchronized (lockObject) { 
    lockObject.notify(); 

那么无论是读者和作家被锁定,等待,并通知-ING在同一最终对象实例。在无法更改的字段上同步是一种很好的模式,因此private final Object或某些最好。此外,你只有一个线程,所以notify()就足够了。

但是,您的代码仍然存在竞争条件问题。您的作者可能(尽管不太可能)在之前致电notifyAll(),读者可以访问wait()。如果通知发生并且没有人在等待,那么它是一个noop,读者在到达wait()时会挂起。

一个更好的解决办法是使用共享AtomicBoolean

private final AtomicBoolean writerDone = new AtomicBoolean(); 
... 
// reader 
while (!writerDone.get()) { 
    synchronized (writerDone) { 
     writerDone.wait(); 
    } 
} 
// writer 
writerDone.set(true); 
synchronized (writerDone) { 
    writerDone.notifyAll(); 
} 

你只是做变化不大,如下:

public static void threadTest(){ 
     Test testing = new Test(); 
     testing.lock = new Object(); 
     testing.reader.start(); 
     testing.writer.start(); 
    } 
    private Object lock; 
    Thread reader = new Thread("reader") { 
     public void run() { 

      System.out.println("reader started"); 

      synchronized (lock) { 
       try { 
        lock.wait(); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
      } 
      for (int i = 0; i < 10; i++) { 
       System.out.println("reader " + i); 

      } 
     } 

    }; 
    Thread writer = new Thread("writer") { 
     public void run() { 
      System.out.println("writer started"); 

      for (int i = 0; i < 10; i++) { 
       System.out.println("writer " + i); 
      } 
      synchronized (lock) { 
       lock.notifyAll(); 
      } 

     } 

    }; 
+0

感谢帮助。 :) –