2013-02-15 32 views
0

我不知道爲什麼我的get方法不起作用。它返回「」。使用wait()和notifyAll()設置和獲取方法

我有生產者和消費者類,使用此類和緩衝區接口,只是已設置和獲取方法。生產者從文件中讀取消費者並將其寫入另一個文件中。生產者和消費者都使用線程。

請幫幫我。提前致謝。

import java.util.Stack; 

public class synchronizedFile implements Buffer { 

public Stack<String> StackBuffer = new Stack<String>(); 

public void set(String value) { 

    synchronized (StackBuffer) { 
     if (StackBuffer.size() <= 15) { 
      StackBuffer.push(value); 
      System.out.println(StackBuffer.toString()); 
      StackBuffer.notifyAll(); 
      System.out.println("Consumer notify"); 
     } else { 
      try { 

       System.out.println("Produser is waitting--------------------------------"); 
       StackBuffer.wait(); 
       System.out.println("Consumer tries to write"); 
       set(value); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

public String get() throws InterruptedException { 

    String Flag = " "; 
    synchronized (StackBuffer) { 
     if (!StackBuffer.isEmpty()) { 

      Flag = StackBuffer.firstElement(); 
      StackBuffer.remove(StackBuffer.firstElement()); 
      StackBuffer.notifyAll(); 
      System.out.println("Producer notify"); 
      return Flag; 
     } else { 
      StackBuffer.wait(); 
      System.out.println("Consumer is waitting --------------------"); 
      get(); 

     } 

    } 

    return Flag; 

} 

} 
+0

您應該始終在測試您正在等待的狀況的循環內呼叫等待。閱讀文檔... – assylias 2013-02-15 13:59:37

回答

0

在這裏,您撥打get()遞歸但扔掉它的結果:

StackBuffer.wait(); 
System.out.println("Consumer is waitting --------------------"); 
get(); 

喜歡的東西Flag = get();return get();會更合適。

(另外我不確定是否輸入​​部分兩次做wait是有效的。也許是,我只是不確定)。

+0

同步是可重入的,所以從設置或從get獲取調用集沒有問題。 – assylias 2013-02-15 13:52:37

+0

這比我想象的容易 - 謝謝 – 2013-02-15 14:07:17

1

您至少在get()方法的else分支中丟失了Flag = get()

除了考慮使用BlockingQueue之外,java.util.concurrent還有一些實現爲併發編程提供了重要的幫助。使用低級別結構waitnotify容易出錯。如果不徹底檢查它,如果你的實現是正確的,我會感到驚訝。

+0

+1也許我們應該有這些預先寫好的迴應:) – 2013-02-15 13:56:04

1

您等待並通知兩種不同的狀態:完全和空白。因此,您必須使用兩個單獨的鎖定對象。這已被覆蓋了一段時間here

基本上,如果您不是爲了使用Stack類或某種類型的賦值而實現此目的,請使用java.util.concurrent中的BlockingQueue。

相關問題