我是java中多线程的新手。我试图运行一个程序,可以模拟多个"作家"谁会把数据写成输出。
我希望作者在某些时候都停止,所以我在他们身上调用wait(),但是它没有工作。我知道问题发生在哪里,但我不知道为什么会发生。
public void run() {
ExecutorService executor = Executors.newFixedThreadPool(nbOfWriters);
try {
// Create a list with all the writers that should run at the same time
Writer[] writers = new Writer[nbOfWriters];
for (int i = 0; i < nbOfWriters; i++) {
writers[i] = new Writer(i);
executor.execute(writers[i]);
}
/*
Expected outcome:
start every writer -> wait 3 seconds
pause every writer -> wait 3 seconds
run every writer -> wait 3 seconds
end
*/
TimeUnit.SECONDS.sleep(3);
for (Writer writer : writers) {
synchronized (writer) {
System.out.println("HERE 1");
writer.wait();
System.out.println("HERE 2");
}
}
TimeUnit.SECONDS.sleep(3);
for (Writer writer : writers) {
synchronized (writer) {
writer.notify();
}
}
Thread.sleep(3);
// End of the test
for (Writer writer : writers) writer.end();
}
catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
finally {
try {
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
catch (InterruptedException ex) {
ex.getMessage();
}
finally {
executor.shutdownNow();
}
}
}
作家只是把东西写成输出(这里不重要)。 我已经添加了打印声明&#34; HERE 1&#34;和&#34; HERE 2&#34;显示程序失败的位置。基本上&#34; HERE 2&#34;永远不会到达。
理论上应该发生的是,我将数据写入输出3秒钟,然后3秒内没有任何内容,然后再将数据写入输出。
实际输出是: 东西被写为输出3秒钟。 &#34; HERE 1&#34;打印。 东西继续显示为输出,没有暂停,没有&#34; HERE 2&#34;而程序永远不会停止。
在我看来,wait()正在停止错误的线程。
答案 0 :(得分:0)
wait()
的文档说:
导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法。
所以主要线程是在"HERE 2"
之前等待的东西,因为它等待了,它永远不会到达notify
。
我不确定是否有明确的方法来做你想要的事情(告诉另一个线程等待)。有一些弃用的API,很好地解释了为什么你不应该使用它们:https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
答案 1 :(得分:0)
不应该像其他方法那样在特定的编写器线程中调用
writer.wait()
吗?
没有
声明writer.wait();
使用writer
对象作为monitor。监视器旨在以非常特定的方式使用*。它允许一个线程等待一些(可能是未知的)其他线程来完成任务。想要进行等待的线程通过调用o.wait();
一个线程无法使 make 另一个线程调用一个函数。一个线程无法使另一个线程做任何事情。线程执行他们正在执行的代码告诉他们要做的事情,并且在一个设计良好的程序中,该代码告诉他们彼此合作。线程A可以通过询问线程B来执行某些操作,但是你可以编写在线程A中运行的代码来执行查询,并且由你自己编写在线程B中运行的代码,该代码可以识别被问到什么时候,然后做任何事情。
*请参阅Oracle "guarded block" tutorial 注意!该教程没有使用&#34; monitor&#34;这个词,但它谈到了相同的模式。