In a Swing-app is it okay to invoke开发者_开发知识库 System.exit()
from any thread? (e.g. on the EDT?)
You should not be calling System.exit()
if you can help it.
The best way to exit a java process is to let all threads exit normally. This will terminate the VM.
In your main JFrame
, you should setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
.
Then you can call frame.dispose()
to close the JFrame
and exit the EDT.
Since the VM is terminated after the System.exit()
call I don't think it makes any difference from which thread the call is being made.
You can call it from any Thread, but it is kind of rude to use it IMHO. The virtual machine will be terminated, no matter what else is running.
I prefer to dispose()
or just close (having setDefaultCloseOperation(DISPOSE_ON_CLOSE)
) any displayed window (JFrame, JDialog, ...). If there are only daemon threads running, the virtual machine will be terminated. If there is some live non-daemon thread, the JVM will not terminate and the thread can finish its work.
Doing so, I always can include (parts of) one program in another without having to worry if one of them will accidentally terminate the other.
There are very few situation where the JVM really needed to be "killed"...
System.exit()
terminates not the running threads but the virtual machine itself. So it can be called from whatever thread, the result is always the same, and if the VM dies, all possible inconsitent states in threads will be non-existent at once.
There is absolutely nothing wrong with calling System.exit from any thread you wish. Letting it exit "normally" does not work in practice, because you'll find that the app will be hanging around while the GC collects stuff, before the app quits. I've written tons of gui Swing apps, and there is absolutely nothing wrong with calling it. It's not "rude" either. It's the Java way.
There are Swing rules for the EDT thread to terminate normally.
The most important is to make sure that all frames have been disposed. Unfortunately, this may not be that straightforward if you use modal dialogs without parents because Swing will create an invisible parent frame for such dialogs.
In this case, you have to list all frames (you can use Frame.getFrames()
for that) and explicitly dispose()
them.
Of course you must ensure that no Thread
is alive (except daemons ones). Some libraries and even some API from JDK create non-daemon threads, that you have to shut down yourself.
Finally, and most importantly, not calling System.exit() won't work in a Java Web Start environment (take a look at this SO question to find more information).
So, in conclusion, my advice would be to actually call System.exit()
because you don't always know in which environment your application will be launched. But I would add an important point to that: make sure to have a single point from which exit is performed. Calling it from any thread will be OK.
It is safe to call System.exit from any thread but not from the shutdown hook thread. I recently had to debug such flow https://knotgillcup.blogspot.com/2019/08/systemexit-not-working.html
Even more brutal way to terminate JVM is to call Runtime.halt() method.
精彩评论