10

According to Brian Goetz's Java Concurrency in Practice JVM can't exit until all the (nondaemon) threads have terminated, so failing to shut down an Executor could prevent the JVM from exiting.

I.e. System.exit(0) doesn't necessarily work as expected if there are Executors around. It would seem necessary to put some kind of

public void stop() { exec.shutdown() }

methods to all classes that contain Executors, and then call them when the application is about to terminate. Is this the only way, or is there some kind of shortcut to shut down all the Executors?

Joonas Pulakka
  • 36,252
  • 29
  • 106
  • 169
  • I was confusing Executor with Runnable. I deleted my answer as it doesn't make much sense. @skaffman has my vote. – bruno conde Jul 31 '09 at 10:26

5 Answers5

14

There's no shortcut to do them all, no. Also, you should probably call shutdownNow() rather than shutdown(), otherwise you could be waiting a while.

What you could do, I suppose, is when you create the Executor, register it in a central place. Then, when shutting down, just call shutdown() on that central object, which in turn could terminate each of the registered executors.

If you use Spring, then you can take advantage of its factory beans which create and manage the Executors for you. That includes shutting them down gracefully when the application quits, and saves you having to manage them yourself.

skaffman
  • 398,947
  • 96
  • 818
  • 769
  • Central register seems to be a reasonable option. Funny that java.util.concurrent doesn't include such. – Joonas Pulakka Jul 31 '09 at 10:11
  • It's also a shame that Executors is just a bunch of statics, that makes it hard to hide it behind a registration interface without duplicating several dozen method signatures. – skaffman Jul 31 '09 at 10:16
  • I am also facing similar issue. I am not explicitly using ScheduledThreadPoolExecutor. So I dont have any central reference to the same. In such a case, how to access these threadpools? I am trying to gracefully shutdown them in ContextDestroyed method – DecKno Jan 18 '16 at 06:30
9

Decorate the executor with com.google.common.util.concurrent.MoreExecutors#getExitingExecutorService

@Beta
public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor,
                                         long terminationTimeout,
                                         TimeUnit timeUnit)

Converts the given ThreadPoolExecutor into an ExecutorService that exits when the application is complete. It does so by using daemon threads and adding a shutdown hook to wait for their completion.

This is mainly for fixed thread pools. See Executors.newFixedThreadPool(int).

Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54
9

By default, an Executor will create only non-daemon threads. You can override that by supplying the Executor with your own ThreadFactory. Here's an example:

class DaemonThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  }
}

Be cautious, though, because the JVM will exit right away even if these threads are busy doing useful work!

5

You can also provide an implementation of ThreadFactory that marks created threads as daemon threads. I prefer a clean shutdown mechanism (with lifecycle methods) but there are cases where you don't need guarantees about the state/completion of uncompleted tasks when this can be appropriate.

shuckc
  • 2,766
  • 1
  • 22
  • 17
  • Thanks for pointing out this option. Actually some of my executors should be daemon threads, they just happen to be non-daemon ones because that's what Executors.newXXXExecutor():s do by default. – Joonas Pulakka Jul 31 '09 at 12:13
0

Probably he meant to say JVM can't stop on its own until nondaemon threads are finished. Its like running a simple class from command like java SomeClass and after the execution of main method JVM stops.

System.exit is a JVM termination command, even if daemon threads are running JVM will shutdown.

Bhushan Bhangale
  • 10,921
  • 5
  • 43
  • 71
  • 1
    As Goetz wrote, *nondaemon* threads can prevent JVM from exiting. Actually I've experienced this. Debugger shows that the app can jam to System.exit(0) infinitely, but it seems to be nondeterministic behavior. Usually it doesn't jam, but sometimes it does. – Joonas Pulakka Jul 31 '09 at 10:06