Java 唤醒等待的线程
此类与执行器一起工作。问题是,在某个时刻我想关闭它,但即使我将terminateRequested更改为“true”,它也不会帮助那些在“takeTask”中等待的线程,因为此时的向量任务总是空的。 我需要它们以某种方式到达run()中的“e.shutDown()”行Java 唤醒等待的线程,java,multithreading,Java,Multithreading,此类与执行器一起工作。问题是,在某个时刻我想关闭它,但即使我将terminateRequested更改为“true”,它也不会帮助那些在“takeTask”中等待的线程,因为此时的向量任务总是空的。 我需要它们以某种方式到达run()中的“e.shutDown()”行 您需要中断while tasks.isEmpty(){循环和while(!terminateRequested){循环 所以我建议当你这么做的时候 } catch (InterruptedException e) { e
您需要中断
while tasks.isEmpty(){
循环和while(!terminateRequested){
循环
所以我建议当你这么做的时候
} catch (InterruptedException e) {
e.printStackTrace();
}
你把它改成
} catch (InterruptedException e) {
terminateRequested = true;
return;
}
由于我看不到你的giveSolution
方法,我不能告诉你必须改变它
或者,您可以从
takeTask
方法通过InterruptedException
。因为您使用的是executor服务,所以您可以调用它的方法,该方法将主动关闭线程,而无需等待
根据将Object.wait和Object.notify与java.util.concurrent气味相结合,您需要打破while(tasks.isEmpty()的循环 因此,如下更改代码:
public class RunnableStudent implements Runnable{
private Thread thread;
public void run() {
thread = Thread.currentThread();
while(!terminateRequested){
this.takeTask();
this.giveSolution();
}
e.shutdown();
}
private synchronized void takeTask(){
while(tasks.isEmpty()){
try {
this.wait();
} catch (InterruptedException e) {
break;
}
}
DoSomeWork();
}
public synchronized void shutDown(){
terminateRequested = true;
thread.interupt();
}
首先,如果您有三个不同的RunnableStudent实例(每个线程的每个实例),并且假设任务和terminateRequested是本地变量,则不需要同步。因为线程之间没有共享的内容。
第二,如果您使用的是执行器,那么您可以使用线程池,在这种情况下,您不需要等待并通知自己,一旦工作完成,池中的所有线程(池InItalize时配置的n个线程)将等待下一个请求(通过executors.submit/execute)。您可以根据您的情况在任何给定点使用shutdown/shutdownNow。
最后,要回答您的问题,只需将taketask()中的while循环更改为if conditon.您的所有问题都会解决。因为您的等待逻辑在运行方法中的main while循环中仍然有效。
我可以看看terminateRequested是如何定义的吗?terminateRequested是一个布尔值。我有3个RunnableStudent实例,完成后我只调用s.shutDown()您是否检查过terminateRequested是否易变?我相信java提供了
interrupted
标志。这就是为什么您需要自己发明terminateRequested
的原因?我不希望任何东西被中断。我只想在完成后自己发出关闭请求。这就是我需要terminateRequested的原因R
public class RunnableStudent implements Runnable{
private Thread thread;
public void run() {
thread = Thread.currentThread();
while(!terminateRequested){
this.takeTask();
this.giveSolution();
}
e.shutdown();
}
private synchronized void takeTask(){
while(tasks.isEmpty()){
try {
this.wait();
} catch (InterruptedException e) {
break;
}
}
DoSomeWork();
}
public synchronized void shutDown(){
terminateRequested = true;
thread.interupt();
}