Whenever I call shutdownNow()
or shutdown()
it doesn't shut down. I read of a few threads where it said that shutting down is not guaranteed - can someone provide me a good way of doing it?
ExecutorService must be shutdown explicitly to reclaim the resources (CPU & Memory) occupied by threads which have already finished their job but still exist.
Using shutdown() and awaitTermination() In general, the ExecutorService will not be automatically destroyed when there is no task to process. It will stay alive and wait for new tasks to come.
An unused ExecutorService should be shut down to allow reclamation of its resources. Method submit extends base method Executor.
In the specific case of an ExecutorService , I would vote for supporting thread interruption rather than a flag. In many frameworks, the service will be terminated with shutdownNow() .
The typical pattern is:
executorService.shutdownNow(); executorService.awaitTermination();
When calling shutdownNow
, the executor will (generally) try to interrupt the threads that it manages. To make the shutdown graceful, you need to catch the interrupted exception in the threads or check the interrupted status. If you don't your threads will run forever and your executor will never be able to shutdown. This is because the interruption of threads in Java is a collaborative process (i.e. the interrupted code must do something when asked to stop, not the interrupting code).
For example, the following code prints Exiting normally...
. But if you comment out the line if (Thread.currentThread().isInterrupted()) break;
, it will print Still waiting...
because the threads within the executor are still running.
public static void main(String args[]) throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(new Runnable() { @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) break; } } }); executor.shutdownNow(); if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) { System.out.println("Still waiting..."); System.exit(0); } System.out.println("Exiting normally..."); }
Alternatively, it could be written with an InterruptedException
like this:
public static void main(String args[]) throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(new Runnable() { @Override public void run() { try { while (true) {Thread.sleep(10);} } catch (InterruptedException e) { //ok let's get out of here } } }); executor.shutdownNow(); if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) { System.out.println("Still waiting..."); System.exit(0); } System.out.println("Exiting normally..."); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With