I've just run into an interesting issue. It seems that if, in Java, a thread calls System.exit() it cannot then be joined via Thread.join().
This is causing me issues as I want to use a shutdown hook to clean up after my application, such as:
Runtime.getRuntime.addShutdownHook(new Thread() {
public void run() {
reader.join();
writer.join();
in.close();
out.close();
}
});
The idea is that it ensures that the threads have finished with their respective resources, before closing those resources. The problem is that there a 3 situations by which the shutdown hook can be invoked. They are:
- User hits [ctrl] + [C].
- Reader thread completes, and calls
System.exit(). - Writer thread completes, and calls
System.exit().
The first case, where the user hits [ctrl] + [C] works fine. But in either of the other 2 cases, the shutdown hook blocks forever. This is a knock-on effect of the fact that one Thread.join(), which is called against a thread having already called System.exit(), blocks forever.
Thus, I have 2 questions. Firstly, I know that I could use Thread.join(long millis) instead so that they won't block indefinitely, but can anyone think of a more elegant solution? Secondly, while one can call Thread.join() against the same thread twice and on the second occasion it will simply return immediately, does anyone know of a reason why calling Thread.join() against a thread that has already called System.exit() blocks indefinitely and doesn't just return immediately?
System.exit()and instead arrange a proper cleanup and let the JVM exit naturally?System.exit()is invoked after the virtual machine has begun its shutdown sequence then if shutdown hooks are being run this method will block indefinitely." - do you callSystem.exit()twice by any chance? (Reference)