Java: Force stopping of ExecutorService threads

34,083

Solution 1

ExecutorService.shutdownNow() will try to stop all the executing threads..

Here is a quote from javadoc

List<Runnable> shutdownNow()

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so if any tasks mask or fail to respond to interrupts, they may never terminate.

Solution 2

Instant thread termination is never guaranteed, unless the thread checks periodically for isInterrupted() flag (or is waiting in interruptable method, i.e. which throws InterruptedException).

Consider implementing your worker threads in manner, when they check periodically for isInterrupted(). This may be something like that:

public void run() { 
  byte[] data;
  do {
     data = receiveDataChunk(timeout);
     processData(data);
  } while(!isInterrupted() && data != null);
}

Solution 3

Since downloading a torrent probably involves blocking IO operations, simply calling cancel()/shutdownNow() won't be enough, because blocking IO operations are not guaranteed to terminate when their respective threads are interrupted.

You also need to close the underlying sockets in order to cancel blocking IO, see How to terminate a thread blocking on socket IO operation instantly?.

Solution 4

ExecutorService.submit(...) returns a Future<?> that has a cancel() method. You should keep track of these can call it when you want each task to stop.

Share:
34,083
Clark
Author by

Clark

Updated on October 16, 2020

Comments

  • Clark
    Clark over 3 years

    My code:

    
    String[] torrentFiles = new File("/root/torrents/").list();
    
            if(torrentFiles.length == 0 || torrentFiles == null)
            {
                System.exit(0);
            }
    
            ex = Executors.newFixedThreadPool(3);
    
            for(String torrentFile : torrentFiles)
            {
                ex.submit(new DownloadTorrent("/root/torrents/" + torrentFile));
            }
    
            ex.shutdown();
    
            try
            {
                ex.awaitTermination(30, TimeUnit.MINUTES);
            }
            catch(InterruptedException ex1)
            {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1);
            }
    

    But sometimes torrent downloading takes unknown time value and «awaitTermination» not works as I want. I need to stop all executed threads instantly after half an hour but as I know «awaitTermination» just only use interrupt() method which works only in loops or waiting. So timeout not works if this moment happens. So, how to?

  • pintxo
    pintxo almost 13 years
    If he has not implemented a check on Thread.interrupted() in his implementation this will have no effect.
  • Akshay
    Akshay about 9 years
    I am also using shutdownNow() to stop all the other executing threads but I am able to stop a thread which is waiting for a service response. If I put the thread to sleep then it stops it immediately but in the pervious case it doesn't. Is there any specific reason for that?
  • Evgeni Sergeev
    Evgeni Sergeev about 8 years
    I'm not sure about the direct question, but instead of the while loop, a better pattern in such cases (where you can't tell from just looking at the code that it will terminate) is to say e.g. for (int retries = 0; retries < 1000; ++retries). Also, add a 10 ms wait between retries, or at least yield(). If it reaches 1000, log an error. (Instead of 1000 it should be some large number that is entirely unreasonable to expect if it behaved correctly.)
  • skm
    skm almost 7 years
    @Akshay - yes there is reason for that happening. Thread.sleep() checks for interruption status and if the thread is already interrupted , it then throws InterruptedException. However in absence of such blocking thing happening, as mentioned in doc , There are no guarantees beyond best-effort attempts to stop processing actively executing tasks