Search code examples
javamultithreadingexecutorservicecancellation

How to cancel an ExecutorService in java


I wrote an application that runs some threads using ExecutorService and waits until they finish like this:

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

sometimes I need to cancel the execution of these threads (The entire ExecutorService).
I tried exService.shutdownNow() but it throws java.lang.InterruptedException and doesn't cancel threads.
How can I cancel execution of these threads?


EDIT: T1 class code added as nanda's request

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

Solution

  • My problem with Future#cancel() is that subsequent calls to get() throw a CancellationException. Sometimes I still want be able to call get() on the Future in order to retrieve a partial result after the shutdown of the executor service. In that case one can implement the termination logic in the callables that you submit to the executor service. Use a field like

    private volatile boolean terminate;
    
    public void terminate() {
        terminate = true;
    }
    

    and check for terminate in the callable as often as required. In addition, you have to remember your callables somewhere so you can call terminate() on all of them.