In a situation where a fatal exception occurs, it can be assumed that the program is no longer in a safe state to run and should be terminated as soon as possible. However, I would like to inform the user what fatal error has occurred without requiring them to go searching through log files. Is the best solution to terminate all other executing Threads, only leaving the current thread alive for calling up a JDialog?
This was my attempt at the solution:
public void killAlienThreads() {
Thread[] threads;
while ((threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0])).length != 1) {
for (Thread thread : threads) {
if (thread != Thread.currentThread())
thread.stop();
}
}
}
After this method is called, the current thread goes on to alert the user of the issue, and then close off the program once the remaining dialog is disposed.
There are many issues with this code. For one, new threads could be created while attempting to shut down all of them, this requires a loop that only breaks when it knows only the current thread is left. Also, as Eclipse warns me, Thread.stop() is deprecated, however Thread.interrupt() is not guaranteed to immediately stop a thread. Regardless, instead of terminating all other threads, this method simply gives me a barrage of InterruptedExceptions.
So, how can a program in an "unsafe state" be safely terminated while still allowing for an error dialog to inform the user?
EDIT:
Let me explain a couple things to make my question more clear. When I say "fatal exception" I mean a checked Exception (not an Error) that my program has caught and does not know how to deal with. When one of these errors occurs it can be assumed that the program is no longer in a functional state (or it is "unsafe") and should be terminated as soon as possible. However, waiting for the user to click the "OK" button on an error dialog can take an indefinite amount of time. So, I wish to terminate the program immediately when a "fatal exception occurs" without having to wait for the user to acknowledge the error dialog and close it.
While throwing a proper exception generally leave a lot of objects in a valid state, calling an unsafe method like Thead.stop() can completely corrupt important state and cause even more bad side effects.
The safest way is to let the main process die as quickly as possible and use another daemon process to report the error.
If you have to do it from within the JVM, you'll probably have to look at debugging or instrumentation APIs as it is not possible to interrupt a thread that does not call interruptable methods.
Related
In my JavaFX 8 app, I have a thread that runs a loop and occasionally updates the UI. Somewhere in this thread, there's an exception causing me grief. Finding it wouldn't be a problem, except exceptions on worker threads don't seem to be logged to System output the same as those on the main program thread.
What I mean is, when I run the program, if something breaks in main(), IntelliJ prints the exception message and a stack trace to the Run view (standard out, AFAIC). On the other hand, if something breaks in my thread, I don't get the same verbose output. In fact, most of the time, I don't get anything at all - just a mysteriously non-functioning program.
Is there another step I need to take to capture errors in worker threads? Is my environment misconfigured? This makes debugging next to impossible - any help appreciated!
Between Samuel's comment and some searching, I've got my answer; Runnables tend to consume their errors, so they're never thrown up to the main thread. This means that with no error handling, they simply disappear and the thread is broken.
The solution in my case is to add try/catch blocks in my task. This is dumping errors the way I expect now.
(I guess your answer/comment means I should turn my comment into an answer.)
Depending on your threading model exceptions are not propagated to the main thread, they just kill the thread they are thrown from. You might benefit from adding a try/catch to your "run" method when starting the thread.
I've finally managed to implement Thread.interrupt() into my program instead of Thread.stop(). I am however not sure that I've done this well.
I have a class which extends Thread and declares several methods. EVERY method has been made to throw InterruptedException (Each method performs I/O intensive operations, some of which take several minutes to complete, I have therefore not used a thread-safe flag as the flag would not get checked until after the operation completed). I have also added the following code at several places within these methods to throw the exceptions:
if (this.isInterrupted()) throw new InterruptedException();
Within the run() method I execute all methods within a try/catch for InterruptedException. If caught, I execute Process.destroy() and BufferedReader.close() for my class variables.
This all works, and seems to work very well, however I have a couple of questions:
Is it correct to have more than 10 methods, all of which throw InterruptedException? Is there a better way to do this?
Is it correct to bloat the methods with checks for isInterrupted()?
At the end of the catch InterruptedException block, must I execute a 'return', or 'null' certain values to make the Thread available for GC? If I re-create the Thread it takes longer than usual to initialize.
Finally, are there any issues/enhancements related to what I've done?
Thanks in advance for your help!
Thread interruption in Java doesn't mean stopping the execution of that thread. It is not stop, it is interrupt. A thread can be interrupted when something fundamental and crucial changes, telling the thread that its execution context, its task or its enviroment changed in some significant way. A thread reaction to this message is implementation specific. It can be stop, it can be restart or any other action. A thread that doesn't handle interruptions cannot be interrupted, but its behaviour can still be altered, for example, by using a shared variable.
For example, imagine you have a number of threads, all searching through a part of a problem space for a solution. When one thread finds a solution, it can interrupt other threads, because their search for a solution is no longer relevant. A solution has already been found.
Or imagine one continuously working main thread and one network communication thread. Each time the network thread receives a messsage, it interrupts the working thread with the message. Based on what the message and the context is, the worker thread may decide what to do next. For example, if the message was "STOP", then it could stop all execution immediately. If the message was "RESET", it could start again from scratch or maybe not from scratch and reuse some previous work, based on the execution context.
Is it correct to have more than 10 methods, all of which throw
InterruptedException? Is there a better way to do this?
No, this is perfectly fine, as long as you know what you are doing. If you implement interruptions to just stop the threads, there is no need to throw InterruptedExceptions. A Thread's run() method is it's first, and the exception will not go any further the stack.
Is it correct to bloat the methods with checks for isInterrupted()?
Depending on the context. The checks would be usually added before some crucial code. Usually it is added as a first item in the loop block.
At the end of the catch InterruptedException block, must I execute a
'return', or 'null' certain values to make the Thread available for
GC? If I re-create the Thread it takes longer than usual to
initialize.
No. Once the Thread exists from the run() method, it's left at GC's mercy. Shared variables will not be GC'ed, as long as they are still referenced by other objects.
As many others I have a problem killing my thread without using stop().
I have tried to use volatile on a variable with a while loop in my threads run() routine.
The problem is as far as I can see, that the while loop only checks the variable before every turn. The complex routine Im running takes a long time, and because of that the thread is not terminated immediately.
The thread I want to terminate is a routine that connects to another server and it uses a looooong time. And I want to have an abort button for this. (Terminating the thread). I'll try to explane with some code.
class MyConnectClass{
Thread conThread;
volitile boolean threadTerminator = false;
..some code with connect and abort button..
public void actionPerformed(ActionEvent e) {
String btnName = e.getActionCommand();
if(btnName.equalsIgnoreCase("terminate")){
threadTerminator = true;
conThread.interrupt();
System.out.println("#INFO# USER ABORTED CURRENT OPERATION!");
}else if(btnName.equalsIgnoreCase("connectToServer")){
conThread = new Thread() {
public void run() {
while(threadTerminator == false){
doComplexConnect(); //Uses a loooong time
}
}
}
conThread.start();
}
}
}
How can I kill my "connection" thread instantly?
Thanks.
Java abandoned the stop() approach in Threads a while back because killing a Thread ungracefully caused huge problems in the JVM. From the Javadoc for stop():
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
In most cases, it is up to you to check the threadTerminator var whenever it is safe for you to terminate, and handle the thread exit gracefully. See http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
If you are doing long I/O, you may be in trouble. Some I/O operations throw an InterruptedException, in which case, you can interrupt the thread, and, if you were in that I/O, that exception will be thrown more or less instantly, and you can abort and cleanup the thread. For this reason, interrupting a thread is preferable to using a special custom threadTerminator variable - it's much more standard. In you main code outside of the I/O, check for interrupted() or isInterrupted() periodically (instead of threadTerminator == false).
If you are doing I/O that doesn't throw InterruptedException, sometimes you can close the Socket or similar, and catch the IOException. And sometimes you are stuck.
Why don't you interrupt the thread and just move on, letting it hang until it finishes? The user could initiate a different action (thread) while the old thread finishes gracefully (which, from what I see you are pretty much doing already btw)
The downside of this that you have trouble when the user starts clicking "connectToServer" a lot (many threads), or when the threads fail to terminate (hanged threads). But maybe it's sufficient for your purpose?
Edit:
It would be simple to implement a mechanism that prevents spawning a new conthread unless "it's good to go" (e.g., use a semaphore).
The tricky part will be deciding whether it's good to open a new connection. You could ask the original thread (I.e. have a isalive() method), or the party you are trying to connect to. Or you could go for a timeout solution. For example, you could let conthread update a timestamp and decide it's dead if the timestamp isn't updated for 1 min etc. The most generally applicable solution would probably be the timeout solution.
I have a program where I compile java code a user types into a text field, and then run it. A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up.
The GUI has an abort button that should stop the thread. My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). Any advice or alternative solutions? Hopefully some fresh perspectives could help squash this issue.
Edit:
Here's a sample bit of user submitted code:
public class RunMe extends SomethingThatRuns {
public void run() {
int i = 0;
while (i = 0) {
//Prepare to get stuck!
}
}
}
I'll compile this class, and then run it. This is where it will get stuck, and the run() method can never finish, or even loop to check a flag.
You can run it in a new JVM so you can kill it when you want.
Thinking about security this may be a good thing to do too.
Call stop() on the thread.
Yes, this is a deprecated method. However, it really shouldn't be "deprecated", it should be "dangerous." In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases.
Make sure that your program doesn't use any data that are manipulated by this user thread; or, if you do, devise some transactional mechanism to exchange data safely between the threads.
Even this method isn't guaranteed to terminate the thread. For example, the user can catch the resulting Throwable and ignore it. Or, the thread implementation might not respond to stop() calls if the thread is in some native code. But it's your best chance.
The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. Fix that, and everything else will become easier to deal with.
Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. Forcefully destroying threads just isn't the right way to manage these situations.
You can use them to insert a interrputed check in every loop and maybe in other places too.
I can see two options:
As you compile the user code you can edit it before. You may use
ANTLR to parse and modify the code.
There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already
compiled.
I don't think it is easy but it might be a way.
interupt(); the Thread in the gui
and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops
At a high level, you are asking how one thread might go about stopping another thread. To that end, see this SO question Stopping a Thread in Java?.
I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be broken down into two questions:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt() on a Thread.
In practice, the normal use-cases for interrupt() involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.
Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit(). (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)
On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)
1) If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
One example is if your Runnable objects are executed using an ExecutorService and shutdownNow() is called on the service. And in theory, any 3rd-party thread pool or thread management framework could legitimately do something like this.
2) If I'm never ever interrupting other threads myself using interrupt() ... what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need analyze the codebase to figure out what is making the interrupt() calls and why. Once you have figured that out, you can work out what >>your<< part of the app needs to do.
Until you know why InterruptedException is being thrown, I would advise treating it as a hard error; e.g. print a stacktrace to the log file and shut down the app. (Obviously, that's not always the right answer ... but the point is that this is "a bug", and it needs to be brought to the attention of the developer / maintainer.)
3) How do I find out who / what is calling interrupt()?
There is no good answer to this. The best I can suggest is to set a breakpoint on the Thread.interrupt() and look at the call stack.
If you decide to integrate your code with other libraries, they can call interrupt() on your code. e.g. if you decide in the future to execute your code within an ExecutorService, then that may force a shutdown via interrupt().
To put it briefly, I would consider not just where your code is running now, but in what context it may run in the future. e.g. are you going to put it in a library ? A container ? How will other people use it ? Are you going to reuse it ?
As others have pointed out, interrupting a thread (actually, interrupting a blocking call) is usually used for purposes of exiting cleanly or cancelling an ongoing activity.
However, you should not treat an InterruptedException alone as a "quit command". Instead, you should think of interrupts as a means to control the running status of threads, much in the same way as Object.notify() does. In the same way that you'd check the current state after waking up from a call to Object.wait() (you don't assume that the wakeup means your wait condition has been satisfied), after being nudged with an interrupt you should check why you were interrupted. There is usually a way to do this. For example, java.util.concurrent.FutureTask has an isCancelled() method.
Code sample:
public void run() {
....
try {
.... // Calls that may block.
} catch (InterruptedException e) {
if (!running) { // Add preferred synchronization here.
return; // Explicit flag says we should stop running.
}
// We were interrupted, but the flag says we're still running.
// It would be wrong to always exit here. The interrupt 'nudge'
// could mean something completely different. For example, it
// could be that the thread was blocking on a read from a particular
// file, and now we should read from a different file.
// Interrupt != quit (not necessarily).
}
....
}
public void stop() {
running = false; // Add preferred synchronization here.
myThread.interrupt();
}
The problem with the question is "I". "I" usually refers to a single instance of a class. I mean by that, that any particular piece of low-level code (class) should not rely upon the implementation of the entire system. Having said that you do have make some "architectural" decisions (like what platform to run on).
Possible unexpected interrupts coming from the JRE are canceled tasks in java.util.concurrent and shutting down applets.
Handling of thread interrupts is usually written incorrectly. Therefore, I suggest the architectural decision to avoid causing interrupts where possible. However, code handling interrupts should always be written correctly. Can't take interrupts out of the platform now.
You could learn this by creating your own thread class (extending java.lang.Thread) and overriding interrupt() method, in which you record the stacktrace into, say, a String field, and then transfer to super.interrupt().
public class MyThread extends Thread {
public volatile String interruptStacktrace; // Temporary field for debugging purpose.
#Override
public void interrupt() {
interruptStacktrace = dumpStack(); // You implement it somehow...
super.interrupt();
}
}
As already mentioned, another library can interrupt your threads. Even if the library doesn't have explicit access to the threads from your code, they can still get the list of threads that are running and interrupt them that way with the following method.
I think I understand why you are a bit confused about interruption. Please consider my answers in line:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
Firstly you may interrupt other threads; I know that in JCiP it is mentioned that you should never interrupt threads you do not own; however, this statement has to be properly understood. What it means is that your code which might be running in any arbitrary thread should not handle interruption because since it is not the owner of the thread it has no clue of its interruption policy. So you may request interruption on other threads, but let its owner take the course of interruption action; it has the interruption policy encapsulated within it, not your task code; at least be courteous to set the interruption flag!
There are many ways why there could be interruptions still, may be timeouts, JVM interrupts etc.
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need to be very careful here; if you own the thread which threw InterruptedException (IE), then you know what to do upon catching it, say you may shutdown your app/service or you may replace this killed thread with a new one! However, if you do not own the thread then upon catching IE either rethrow it higher up the call stack or after doing something (may be logging), reset the interrupted status so that the code which owns this thread, when control reaches it, may learn that the thread was interrupted and hence take actions as it will since only it knows the interruption policy.
Hope this helped.
The InterruptedException says that a routine may be interrupted, but not necessarily that it will be.
If you don't expect the interrupt then you should treat it as you might any other unexpected exception. If it's in a critical section where an unexpected exception could have heinous consequences, it might be best to try and clean up resources and gracefully shutdown (because getting the interrupt signals that your well-engineered application that doesn't rely on interrupts is being used in a way it wasn't designed, and so there must be something wrong). Alternatively, if the code in question is something non-critical or trivial, you might want to ignore (or log) the interrupt and keep going.