我的理解是,在消费者收到同步变量更改的通知后,如果消费者Thread
退出并退出,则没有什么可以阻止生产者继续运行。处理生产者线程的正确方法是什么?是否有任何东西阻止从消费者的 run()
方法调用 Thread.interrupt()
?
我正在尝试执行以下操作:
//in consumer
public void run() {
synchronized( checkSolution) {
while (!checkSolution.getIsSolutionValid) {
try{
checkSolution.wait()
} catch( InterruptedException ignore) {}
}
//valid soln received
System.out.println("reference");
checkSolution.interrupt();
doAmazingWorkWithSolution();
}
//MARK
}
//in producer (checkSolution)
public synchronized boolean getIsSolutionValid() { return isSolutionValid; }
public void run() {
while(true) {
try{
synchronized( this) {
if( fSolution.size() != correctSize) {
isSolutionValid = false;
Thread.sleep(500);
} else {
System.out.println(" Solution is correct size.");
isSolutionValid = true;
notifyAll();
}
}
} catch(InterruptedException ie) {
//Thread.currentThread().interrupt();
return;
}
}
}
现在,这是我注意到但我真的不明白的:
在任何成功的中断下,生产者的中断标志都会被设置,但它会在最终关闭之前多次执行
else
block 中的代码。如何避免在notify
期间发送垃圾邮件 if/else 语句?如果我将 checkSolution.interrupt() 和“amazing work”方法调用移动到标记为
//MARK
的行,它的中断速度会明显变慢,执行惊人的工作调用,但奇怪的是从不打印 `println("reference");如果我从
InterruptedException
中删除 return 语句,它会收到中断并最终在Exception
block 中执行一步,但会向 else 语句发送无数次垃圾邮件,然后开始再次插入Thread.sleep
block ,就好像中断标志已被重置一样。生产者的
InterruptException
中的Thread.currentThread().interrupt();
是我在其他人的代码中看到的东西,但无论我是否包含它,它在这里似乎都没有执行任何操作。
这些都是我感到困惑的小事情。主要问题是在消费者获得所需内容后,如何尽可能高效地关闭生产者,并尽可能靠近消费者线程。
最佳答案
我认为你的工作水平太低了。如果只有一个生产者和消费者,您可以使用 java.util.concurrent.SynchronousQueue 来阻塞消费者,直到生产者完成其工作。
有关Thread.currentThread().interrupt()
的用途,请参见http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html 。这样做是个坏主意
catch( InterruptedException ignore) {}
在 while
循环中。更多详细信息请参阅链接的文章。
关于java - 在消费者线程收到同步更改通知并退出后,处理生产者线程的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9733704/