RYN*_*RYN 3 java multithreading executorservice cancellation
我编写了一个运行某些线程的应用程序,ExecutorService并等待它们完成,如下所示:
ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(T1);
exService.execute(T2);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)
有时我需要取消这些线程的执行(整个ExecutorService).
我尝试exService.shutdownNow()但它抛出java.lang.InterruptedException并且不取消线程.
如何取消这些线程的执行?
编辑:T1类代码作为nanda的请求添加
public class TC implements Runnable{
private ExtractedDataBuffer Buffer;
private Scraper scraper;
private String AppPath;
private boolean Succeed=false;
private Map<String,Object> Result=null;
private JLabel StatElement;
public TC(ExtractedDataBuffer Buffer,String AppPath,String XMLfile,JLabel Stat) throws FileNotFoundException {
this.Buffer = Buffer;
this.AppPath=AppPath;
this.StatElement=Stat;
ScraperConfiguration config;
config = new ScraperConfiguration(AppPath + Main.XMLFilesPath +XMLfile);
scraper = new Scraper(config, AppPath);
}
private void extract(){
try{
mainF.SetIconStat("working", this.StatElement);
scraper.execute();
if(scraper.getStatus()==Scraper.STATUS_FINISHED){
this.Succeed=true;
Map<String,Object> tmp=new HashMap<String,Object>();
tmp.put("UpdateTime", ((Variable) scraper.getContext().get("UpdateTime")).toString().trim());
Buffer.setVal(this.Result);
mainF.SetIconStat("done", this.StatElement);
}else{
this.Succeed=false;
this.Result=null;
Buffer.setVal(null);
mainF.SetIconStat("error", this.StatElement);
}
}catch(Exception ex){
this.Succeed=false;
this.Result=null;
Buffer.setVal(null);
mainF.SetIconStat("error", this.StatElement);
}
}
public void run() {
this.extract();
}
}
Run Code Online (Sandbox Code Playgroud)
如果将shutdown()更改为shutdownNow(),则在编写的代码中执行的操作正确.但是,请查看shutdownNow()的文档:
除尽力尝试停止处理主动执行任务之外,没有任何保证.例如,典型的实现将通过Thread.interrupt()取消,因此任何未能响应中断的任务都可能永远不会终止.
因此,您的T1和T2可能没有以正确的方式编码,并且不能很好地响应中断.你可以为他们复制代码吗?
-
根据你的代码,我猜需要很长时间的代码是scraper.execute(),对吧?所以在这些方法中,你必须经常检查这样的事情:
if (Thread.interrupted()) {
throw new InterruptedException();
}
Run Code Online (Sandbox Code Playgroud)
如果中断到来,将在catch语句中抛出并捕获InterruptedException,线程将停止.
我的问题Future#cancel()是后续调用get()抛出CancellationException. 有时我仍然希望能够在执行程序服务关闭后调用get()以Future检索部分结果。在这种情况下,可以在您提交给执行程序服务的可调用对象中实现终止逻辑。使用类似的字段
private volatile boolean terminate;
public void terminate() {
terminate = true;
}
Run Code Online (Sandbox Code Playgroud)
并terminate根据需要经常检查可调用内容。此外,您必须在某个地方记住您的可调用项,以便您可以调用terminate()所有它们。
| 归档时间: |
|
| 查看次数: |
7808 次 |
| 最近记录: |