5

我编写了一个应用程序,它运行一些线程ExecutorService并等待它们完成,如下所示:

ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(T1);
exService.execute(T2);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);

有时我需要取消这些线程的执行(整个ExecutorService)。
我试过exService.shutdownNow()了,但它会抛出java.lang.InterruptedException并且不会取消线程。
如何取消这些线程的执行?


编辑:作为南达的要求添加的 T1 类代码

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();
    }    
}
4

3 回答 3

5

如果您将shutdown() 更改为shutdownNow(),那么您在编写的代码中做的事情是正确的。但是,请检查 shutdownNow() 的文档:

除了尽最大努力停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.interrupt() 取消,因此任何未能响应中断的任务可能永远不会终止。

因此,您的 T1 和 T2 可能没有以正确的方式编码,并且对中断的响应不够好。你可以为他们复制代码吗?

--

根据您的代码,我猜需要很长时间的代码是 scraper.execute(),对吧?因此,在这些方法中,您必须不断检查以下内容:

if (Thread.interrupted()) {
   throw new InterruptedException();
}

如果中断来了,InterruptedException 将被抛出并在您的 catch 语句中捕获,并且线程将停止。

于 2011-11-05T21:27:55.347 回答
4

我的问题Future#cancel()是后续调用get()抛出CancellationException. 有时我仍然希望能够在执行程序服务关闭后调用以检索部分结果get()Future在这种情况下,可以在您提交给执行程序服务的可调用对象中实现终止逻辑。使用类似的字段

private volatile boolean terminate;

public void terminate() {
    terminate = true;
}

并根据需要经常检查terminate可调用对象。此外,您必须在某处记住您的可调用对象,以便可以调用terminate()所有对象。

于 2011-11-05T21:21:15.713 回答
2

使用执行器。submit方法,它通过创建和返回Future可用于取消执行和/或等待完成的 a 来扩展基本方法 Executor.execute(java.lang.Runnable):

task = Executor.submit( T1 )
...
task.cancel( true )
于 2011-11-05T21:17:11.343 回答