views:

542

answers:

4

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?

A: 

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
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
+5  A: 

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
Central register seems to be a reasonable option. Funny that java.util.concurrent doesn't include such.
Joonas Pulakka
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
+2  A: 

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
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
+1  A: 

The stand-alone JVM exits automatically when all non-daemon threads exit their run() method.

You can force it to exit "now" with System.exit().

If your program will not exit cleanly, investigate why.

Thorbjørn Ravn Andersen