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?