2017-05-08 79 views
-2

以下代碼沒有通知線程讀取器執行寫入器,然後終止。這是爲什麼? 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'塊中的任何內容,所以沒有什麼可以通知的。) –

回答

0

notifyAll的()不屬於Thread類,但屬於對象的基類;在線程作家,notifyAll的()是作家對象的功能,它可以
清醒其具有螺紋作者對象鎖; enter image description here

+0

所以我怎麼能從writer線程中通知讀者線程。 –

0

以下代碼沒有通知線程閱讀器執行編寫器,然後終止。這是爲什麼?

您的程序沒有完成,因爲寫入程序線程終止,但讀卡器線程卡在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(); 
} 
0

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

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

感謝幫助。 :) –

相關問題