使用wait()和notifyAll()设置和获取方法
我不知道为什么我的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;
}
}
在这里,您拨打get()
递归但扔掉它的结果:
StackBuffer.wait();
System.out.println("Consumer is waitting --------------------");
get();
喜欢的东西Flag = get();
或return get();
会更合适。
(另外我不确定是否输入部分两次做wait
是有效的。也许是,我只是不确定)。
同步是可重入的,所以从设置或从get获取调用集没有问题。 – assylias 2013-02-15 13:52:37
这比我想象的容易 - 谢谢 – 2013-02-15 14:07:17
您至少在get()方法的else
分支中丢失了Flag = get()
。
除了考虑使用BlockingQueue之外,java.util.concurrent
还有一些实现为并发编程提供了重要的帮助。使用低级别结构wait
和notify
容易出错。如果不彻底检查它,如果你的实现是正确的,我会感到惊讶。
+1也许我们应该有这些预先写好的回应:) – 2013-02-15 13:56:04
您等待并通知两种不同的状态:完全和空白。因此,您必须使用两个单独的锁定对象。这已被覆盖了一段时间here。
基本上,如果您不是为了使用Stack
类或某种类型的赋值而实现此目的,请使用java.util.concurrent中的BlockingQueue。
您应该始终在测试您正在等待的状况的循环内呼叫等待。阅读文档... – assylias 2013-02-15 13:59:37