我正在编写一个产生多个并发任务的应用程序.我正在使用线程池来实现它.
可能发生事件发生,使得在任务中完成的计算无效.在这种情况下,我想停止当前正在运行的任务,并开始新的任务.
我的问题:如何停止当前正在运行的任务?我实现的解决方案是存储对任务线程的引用并调用interrupt()此线程.在演示代码中:
public class Task implements Runnable {
private String name;
private Thread runThread;
public Task(String name) {
super();
this.name = name;
}
@Override
public void run() {
runThread = Thread.currentThread();
System.out.println("Starting thread " + name);
while (true) {
try {
Thread.sleep(4000);
System.out.println("Hello from thread " + name);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
}
public void stop() {
runThread.interrupt();
}
public String getName() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
主要方法是:
public static void main(String args[]) {
executorService = Executors.newFixedThreadPool(2);
Task t1 = new Task("Task1");
Task t2 = new Task("Task2");
executorService.execute(t1);
executorService.execute(t2);
executorService.execute(new Task("Task3"));
executorService.execute(new Task("Task4"));
try {
Thread.sleep(12000);
t1.stop();
System.err.println("Stopped thread " + t1.getName());
Thread.sleep(8000);
t2.stop();
System.err.println("Stopped thread " + t2.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好的解决方案,还是有更好的方法来阻止线程池中正在运行的线程?
您可以通过保留对未来的引用来阻止它
Future<?> future = exec.submit( new Runnable() {
while (true){
try{
obj.wait();
} catch(InterruptedException e){
System.out.println("interrupted");
return;
}
}
});
future.cancel(true);
Run Code Online (Sandbox Code Playgroud)
布尔值用于 - 如果运行可能会中断。
我进行了测试并从该线程中得到了一个中断异常。
如果你有cachedThreadPool,你可能需要仔细检查你的可运行对象中是否捕获了异常,然后不要设置回中断标志,因为你的线程将运行另一个未来,如果你设置中断,另一个队列未来可能不会运行。
在您重写的run()方法中,您将永远循环while(true). 标准行为是boolean runIndicator方法run()在启动时将其设置为 true,然后您的循环应该是while(runIndicator). 您的stop()方法应该简单设置,runIndicator = false以便循环的下一次迭代将会失败。