Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - stopping all tasks in ExecutorService

I have a few executor services which schedule local tasks such as reading a file, connecting to db etc. These processes do huge amount of logging, which is extensive based on the fact there are many threads running concurrently, writing their own thing into the log.

Now, at some point in time an exception can be raised, which reaches the main method where all exceptions are caught. I am then shutting down all the services and cancelling each task, hoping to prevent all further messages to the log. Unfortunately, the messages are still showing up after I shut everything down... Any ideas?

UPDATE: Here is some code

public class Scheduler{

private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;

...

public void shutDown() {
    service.shutdownNow();
    for (Future task : cache.values())
        task.cancel(true);
}
like image 287
Bober02 Avatar asked Nov 30 '12 09:11

Bober02


2 Answers

The task will carry on running until it reaches a point where it detects the Thread has been interrupted. This can happen when calling some System or Thread functions and you may get an exception thrown. In your case you probably need to check yourself by calling

Thread.currentThread().isInterrupted()

It is a good idea to do this if your code runs loops and you are expecting to be stopped in this way.

like image 79
pillingworth Avatar answered Sep 22 '22 00:09

pillingworth


When you shutdownNow your executor or call cancel(true) (by the way shutdownNow already cancels the already submitted tasks so your loop is unnecessary) your tasks get interrupted.

Depending on how they react to the interruption, they might then:

  • stop what they are doing immediately
  • stop what they are doing after a while, because the interruption signal is not being checked regularly enough
  • continue doing what they are doing because the interruption signal has been ignored

For example, if your tasks run a while(true) loop, you can replace it with something like:

while(!Thread.currentThread().isInterrupted()) {
    //your code here
}
cleanup();
//and exit

Another example:

for (int i = 0; i < aBigNumber; i++) {
    if (Thread.currentThread().isInterrupted()) { break; }
    //rest of the code for the loop
}
cleanup();
//and exit

Another example, if you call a method that throws InterruptedException:

try {
    Thread.sleep(forever); //or some blocking IO or file reading...
} catch (InterruptedException e) {
    cleanup();
    Thread.currentThread.interrupt();
    //and exit
}
like image 26
assylias Avatar answered Sep 23 '22 00:09

assylias