I have a Swing application that handles Ctrl+C using addShutdownHook(), and it works fine until one of the shutdown tasks I have calls a function that under normal circumstances changes a JLabel text, at which point it hangs.
I assume the problem is that the Swing EDT has either terminated or is waiting for something.
Is there a way to either determine that the EDT has terminated or is "done" (so I can avoid calling Swing methods), or to prevent the usual close-all-the-windows-down behavior on Ctrl-C?
Just to clarify:
I have a method in a class called stop(). Under normal circumstances this can get called (along with its complement start()) and it triggers a cascade of things that causes a JLabel to be updated, for visual feedback that a stop() has occurred.
When my shutdown hook runs, I need to call stop() to gracefully shutdown some resources.
What I'm asking is how I can detect that Swing EDT is not there, so I can rewrite stop() so that it detects a lack of Swing and avoids the call to the Swing functions.
The following hack helps to determine whether JVM is in the process of shutting down without passing any flags around:
private static final Thread DUMMY_HOOK = new Thread();
public static boolean isShuttingDown()
{
try {
Runtime.getRuntime().addShutdownHook(DUMMY_HOOK);
Runtime.getRuntime().removeShutdownHook(DUMMY_HOOK);
} catch ( IllegalStateException e ) {
return true;
}
return false;
}
But don't forget about possible concurrency issues.
Shutdown hooks should not expect other services to be in a known state (e.g. the UI event-handling thread, etc.), because the application has been requested to be shut down. Writing a shutdown hook that tries to update something that isn't 100% within the hook's control can result in this, and other behavior, that will be difficult to troubleshoot.
The addShutdownHook method specifically mentions this case, and warns that you shouldn't try these types of actions, since doing so can easily result in unexpected consequences, such as the lockup you've observed.
From the documentation:
Shutdown hooks run at a delicate time in the life cycle of a virtual
machine and should therefore be coded defensively. They should, in
particular, be written to be thread-safe and to avoid deadlocks
insofar as possible. They should also not rely blindly upon services
that may have registered their own shutdown hooks and therefore may
themselves in the process of shutting down.
In this case, since Swing is a multi-threaded UI system which you do not control, I would recommend not trying to alter anything in the UI at the shutdown stage of you're program's life. Doing so will result in strange, unpredictable, and sometimes non-repeatable situations that can vary from one run to the next, or from one machine to the next, depending on how the threads get scheduled to shutdown. How, and when, another thread stops its work is not designed to happen in a linear, predictable way. As such, any code you write in a multi-threaded program that relies upon another thread being in a certain state at a certain time (unless those threads are clearly communicating with each other about their state), will open you up to these kinds of issues.
I suppose my follow up question would be, "Why do you want/need to alter the JLabel during the shutdown process?" If you want to change the state of something before shutdown, the better way to do it would be catch the keyboard input as a regular event (preventing it from causing the application to close), change the JLabel text, and then start a shutdown of the application yourself via a call to System.runFinalization() and/or System.ext(int)
I ended up setting a flag at the beginning of the shutdown hook, and communicating this (via objects set up ahead of time) to the object with my stop() method, so that it can test this flag and decide whether or not to call the Swing methods.
If the shutdown flag is not set, the Swing methods get called. Otherwise they don't.
Related
I would like to shutdown a thread gracefully. However, once the shutdown is initiated the thread should perform some shutdown operation after ending usual operation.
Both threads use sleeps and/or wait and handle InterruptedException, they also work on tasks in a loop taking only a few milliseconds. So that I expected the while loop to end because Thread.currentThread().isInterrupted() becomes "true".
The problem is that with my code sometimes I get the log "SHUTDOWN" and sometimes not. Also I get "INTERRUPTED" only sometimes, which I understand of course. With another similar thread I never get the "SHUTDOWN".
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new Test());
Thread.sleep(10000);
executor.shutdown();
try {
if(this.executor.awaitTermination(60, TimeUnit.SECONDS)) {
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (GRACEFULLY)!");
} else {
this.executor.shutdownNow();
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (IMMEDIATELY)!");
}
} catch(InterruptedException e) {
this.executor.shutdownNow();
this.loggerFactory.getLogger(this.getClass()).info("CLOSED (IMMEDIATELY)!");
}
class Test implements Runnable {
private volatile boolean isRunning = true;
#Override
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
while(!this.isRunning) {
synchronized(this) {
this.wait();
}
}
// DO SOMETHING LASTING A FEW MILLISECONDS
Thread.sleep(500);
}
} catch(InterruptedException e) {
this.loggerFactory.getLogger(this.getClass()).info("INTERRUPTED!");
}
this.loggerFactory.getLogger(this.getClass()).info("SHUTDOWN!");
// DO SOME SHUTDOWN OPERATION
}
}
EDIT:
After some commentary by OP, an entirely different and much superior solution seems to be available:
Use hooks!
Java has a system to 'install' a shutdown hook. These are called when the VM shuts down... sometimes. If you get SIGTERMed (kill -9) or someone trips over a powercable, or linux kills your process due to excessive memory use, or the kernel dumps, or your VM hard crashes (for example, a core dump in native code), or the device loses power, they don't get called, of course.
But, if someone in the process runs System.exit(), or all non-daemon threads are done, or someone hits CTRL+C or sends SIGKILL (kill, not kill -9) to your process, they get run first, and only when they all finish does the java process actually end.
That sounds like a vastly superior solution here. Your shutdown hook should:
acquire the lock on some private AtomicBoolean.
set the boolean to false (the boolean indicates: May I query this sensor?)
release the lock.
reset the sensor.
return.
And all your normal operation code that reads that sensor should:
acquire a lock on the boolean.
if false, throw or otherwise abort.
perform the sensor read operation.
release the lock.
Nothing should ever touch that sensor without holding the lock (failure to do this would imply maybe messing with that sensor after you've already reset it, which would be bad).
original answer:
I would like to shutdown a thread gracefully.
Why? 'gracefully' is a very nice sounding word, but once you dig into what it means, it's just nasty things. It's a word that means: "That will cause my software to fail, possibly persistently (as in, won't start anymore without cleaning up stuff), if someone trips over a powercable or my app hard-crashes".
A much better design is to have a thread that doesn't need to be shut down. Just pull the plug on it, and all is well.
For example, old filesystems (MS-DOS and early windows age) required graceful shutdowns; failure to do so would lead to persistent issues - the system wouldn't boot at all, you bricked the box. They then had mitigation systems in place (chkdsk systems), but modern OSes are much better. Their filesystem handling setup mostly doesn't care about being 'gracefully' shut down. Just pull the plug on em, they'll be fine, that's what journals do.
So that I expected the while loop to end because Thread.currentThread().isInterrupted() becomes "true".
That's not how you're supposed to use that API.
Here's the basic gist of what the interrupted API does:
Any thread can 'raise the interrupt flag' on any other (someThread.interrupt()).
raising the flag doesn't do anything other than raise the flag, unless a method explicitly decides to look at it.
The method Thread.interrupted() is how you're supposed to read the flag out in order to act upon it, __and not Thread.currentThread().isInterrupted(). The former will check the flag and clear it. The latter merely checks the flag.
Some java methods are specced to respond to the flag being up. You recognize these methods because they throws InterruptedException. There may be more methods; for example, on most OSes, interrupting a thread currently waiting for more bytes to flow in from the network (they are blocked on a read() call on an InputStream obtained from socket.getInputStream()) WILL cause that read call to fail (with an IOException, not an InterruptedException, because read() isn't specced to throw InterruptedEx), but that's no guarantee; on some OSes, it won't, and you can't interrupted that.
The general policy is that the moment you handle an interrupted flag, you lower the flag, and java code does just that: If a method throws InterruptedEx, the flag will be cleared.
Java does not define what you should do if interrupted. Threads don't get magically interrupted; for example, when your VM shuts down (someone hits CTRL+C), that doesn't interrupt any threads whatsoever. Java will just 'pull the plug' on all threads. That's because this is better (see above). Therefore, if a thread is interrupted, that's because you wrote thread.interrupt() someplace, therefore, you decide what it means. Maybe it means 're-read a config file and restart the server listening process'. Maybe it means 'stop calculating chess moves and perform the best move found so far'. Maybe it means 'recheck for a condition'. Maybe it means 'end the thread entirely'. It's up to you. There is no standard.
Note that the various methods specced to respond to interrupt flags (such as wait(): It throws InterruptedException) all share this property: If you call them while the flag is up, they will instantly return by throwing InterruptedException, they never even begin waiting.
So, for your code, given that you wait() already, just make that while(true) and rely on the InterruptedEx.
When executing the command this.setVisible(false), does it stop all threads that are running specifically on that frame?
If not, is there an easy way to stop all of them automatically?
I think we have a conceptual problem here. There are no "threads running on a JFrame." There is one thread, the Event Dispatch Thread, that runs ALL Swing objects, frames, etc.
The EDT (Event Dispatch Thread) does not stop because you made one window invisible. However, if ALL Swing objects become unreachable (eligible for garbage collection) then the Swing EDT does shut down. (The app-note linked below says you can also call Window.dispose() on a frame to make it undisplayable; it then no longer counts for keeping the EDT running.)
The more precise conditions for shutting down the EDT are in this app-note:
Starting with 1.4, the behavior has changed as a result of the fix for
4030718. With the current implementation, AWT terminates all its helper
threads allowing the application to exit cleanly when the following
three conditions are true:
There are no displayable AWT or Swing components.
There are no native events in the native event queue.
There are no AWT events in java EventQueues.
Prior to Java 1.4, the EDT never shuts down. Hopefully you don't need to go that far back.
If you want to shutdown a group of threads, you have to do it manually (other than using some course method like System.exit()). I would look at Executors which enable you to manage threads fairly easily.
No, setting the JFrame visibility to false won't stop all threads you created with new Thread().
If not, is there an easy way to stop all of them automatically?
To stop all of them automatically there is no way (unless terminate all the program)
You need to have them stored in a list or a vector, for example, and then use the method Thread.interrupt()
Something like this:
for(Thread thread : threads) //where threads is a List
{
thread.interrupt();
}
No it does not!
The Thread does still run in background, but you cant interact with the Frame.
To Stop all threads you could do:
System.exit(1) which would terminate all Threads or for every Thread
Thread.sleep(10000000000); which would stop the Thread for a certain amount of time (in milliseconds).
I'm wondering why there seems to be no support for thread level 'shutdown hooks', which run when a specific thread terminates; not when the JVM terminates.
So lets say someone wrote a simple thread with a run method with sudo code like this (intentionally leaving out thread interrupt here for now...):
public void run(){
SeverSocket serverSocket=new ServerSocket(port);
while(!isStopRequested){
Socket socket=serverSocket.accept();
processRequest(socket);
}
runShutdownLogic();
}
public void stopServer(){
isStopRequested=false;
//interrupt thread potentially, see below
}
This thread could die in a few ways:
someone calls stopServer, followed by either...
a. the serversocket.accept accepting one last socket and returning
b. an interrupt sent to intterupt serverSocket.accept
an exception is thrown
Someone kills the thread, directly or through executor service.
The JVM goes down.
In any of these cases we want to run the shutdownLogic method, lets say it does something more then just close the seversocket, some interface with an external source that is important to do no matter how the thread shuts down.
As I understand it this is not very easy to do, in fact it seems hard enough that I feel I must be missing some basic threading feature. the 1a case is simple and works as is. 1b case works so long as the developer doesn't swallow interruptExceptions, something that is done way to often but is easy enough to avoid if you know what an interrupt exception is.
In case of an exception you need to move the shutdown method into a finally block.
In cases 3 & 4 though this gets harder. For 3 I think threads can be killed 'nicely', with an interrupt that one can catch, check to see it's a sigkill, and then force an exit of the code, but this requires even more intelligent handling of a InterruptException that most improperly swallow; plus would get ugly fast if this check has to be done in dozens of locations that can through interrupts. You can't do much for a hard kill, but no one expects proper shutdown logic for a hard kill so that's fine.
For a JVM shutdown...I don't actually know the exact method the threads are killed. I assume a sigkill is sent to the threads with a timeout before a hard kill, I'd have to research it more. If you want to be safe you can add a shutdown hook, but there is no gaurentee of order that shutdown hooks are run and trying to add shutdown hooks for each thread requires careful writing of the hooks to ensure you don't stall or stop the JVM shutdown with a deadlock or unexpected exception in the hook....
If instead of a thread like the one above I have a thread with a finite, but potentially long, processing time, without any waits, it gets even harder since I can't listen for an interrupted exception to know that I need to give up on my threads processing and run the shutdown logic immediately.
Basically, it seems like different method is needed to handle each manner a thread can execute, and needs to be done with every thread. And still in the case of high CPU threads without waits I still don't now how to gaurente a proper shutdown occurs if the thread (not the whole JVM) is killed midway through...
Is there not a simpler solution to all of this? For instance the equivalent of a thread level shutdown hook which will run when that specific thread is being killed, regardless of how it dies; even if JVM itself is not shutting down? Is there some reason a thread level shutdownhook is not possible or dangerous to support, assuming that such doesn't exist.
At least one of the reasons is that there really is not a safe and clean mechanism, which is also why Thread.stop() is deprecated. By creating a (seemingly) simple mechanism for it, people might think that it's a simple issue and use it wildly.
The same issue exists for finalizers and shutdownhooks. They're not reliable, so it's not a good idea to let developers think that it's a normal tool that they're supposed to use.
Yes, Java provides such a mechanism. Simply use a try/finally construction in your run() method, either in your Thread subclass or in your Runnable if you are using a Runnable:
public void run() {
try {
doBody()
}
finally {
doThreadShutdown()
}
}
This should take care of all of the cases that you are looking for, including normal shutdown of the virtual machine, since the virtual machine shuts down only after all nondaemon threads exit. Exceptions would be hard stop of the thread, hard kill of the virtual machine, or if the thread is a daemon thread and the virtual machine exits.
Is there some way to verify that code is executing on the user’s user interface thread (event loop thread)?
This question is the Vaadin equivalent of this question, Swing verify code on Event Dispatch Thread at runtime.
I know how to call UI::access from a background thread to schedule a Runnable to be run on the user-interface thread. My question is how to double-check that some executing code is indeed running on the user-interface thread.
I filed a feature request for this.
UI.getCurrent()
If UI.getCurrent() returns an instance you are (most probably) either:
On a thread started by UI interaction
On a thread that is already initiated with UI::access
To quote the Vaadin 7.3.9 doc:
… In other cases, (e.g. from background threads), the current UI is not automatically defined.
Example Code
boolean uiOrUiAccessManagedThread = UI.getCurrent() != null;
The framework is already full of asserts in various code paths that should only be run on the thread that has locked the UI state. The most important being whenever shared state is accessed.
To benefit from this checking, just make sure your server is run with assertion checking enabled, i.e. by starting it with the -ea JVM parameter.
I'm writing a server, which may be running hostile code. To prevent an attacker from throwing a thread into an infinite loop, I want to enforce a one-second execution time limit.
An InterruptedException can be caught inside an infinite loop, thus allowing an attacker to retain control of the thread. Thus Thread.interrupt() is not an acceptable solution.
My current implementation prevents hostile threads from acquiring any resources (including locks), uses Thread.stop() to terminate execution, and reverts any changes made by the thread. My main complaint is that it uses the deprecated Thread.stop() method; I don't like using deprecated code.
I'm wondering if there is a more industry-accepted solution, short of launching/killing an entirely new JVM, which would have too much overhead for my purposes.
The only way to kill a thread is to use a separate process and kill that process. Thread.stop() throws a ThreadDeath error which can be caught and ignored. i.e. catch(Throwable t) {}
For more details on what Thread.stop() actually does Does Thread.stop() really stop a Thread?
You cannot guarantee that a thread can be stopped as several blocking methods (like sockets) do not respond to interrupt().
I would suggest a very strict security manager so you can be absolutely certain that the malicious code is sandboxed. If you need to be certain then consider a special classloader which ensures that only valid operations are being done.