2013-02-15 71 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。