For some reason I am confused over the following:
Assume that I have Thread A that absolutely needs to execute after Thread B has completed its processing.
A way to do this would be by Thread A joining Thread B.
Trivial example:
public class MainThread {
public static void main(String[] args){
Thread b = new Thread (new SomeRunnable(args[0]));
b.start();
try {
b.join();
} catch(InteruptedException e) {
}
// Go on with processing
}
}
My question is the following: What is the proper way to handle the exception in such a case?
In various example I have seen, even in text-books, the exception is ignored.
So if Thread A needs to be sure that Thread B is completely finished before proceding, if I end up in the catch due to an exception, can it be the case that Thread B may still actually be runnable/running? So what is the best way to handle this exception?
First of all you must understand what causes this exception to be thrown. Calling stop() on a thread is currently deprecated, instead when you want to stop a thread you are interrupting it by calling thread.interrupt(). This has no impact on a thread (!), the thread must explicitly check interrupted flag once in a while and stop processing gracefully.
However if the thread sleeps, waits on a lock or on another thread (by using join() like in your example) it cannot check this flag immediately or often enough. In these cases JVM will throw an exception from blocking method (let it be join()) signalling your thread that someone just tried interrupting it. Typically you can ignore that exception (meaning - do not log it) - it's the side effect that matters. For example breaking out of the loop:
public void run() {
try {
while(!isInterrupted()) {
Thread.sleep(1000);
//...
} catch(InterruptedException e) {
//no need to log it, although it's a good idea.
}
}
It's not a problem that you didn't log that exception - but you escaped from the loop, effectively terminating the thread.
Now back to your question. When your Thread A is interrupted it means some other thread requested terminating it, probably because the whole JVM shuts down or web application is being undeployed. In this case you shouldn't be doing anything except cleanup.
Moreover it most likely means Thread B is still running. But what JVM is trying to say is: "Danger! Danger! Stop waiting for whatever you were waiting for and run!".
What is the proper way to handle the exception in such a case?
Any time you get an InterruptedException the current thread should consider itself to be interrupted. Typically, that means that the thread should clean up after itself and exit. In your case, the main thread is being interrupted by another thread and should probably interrupt the Thread a that it started in turn, and then quit.
Although it is up to you whether the interrupt should be ignored I would suggest that it is a bad practice. If you were using the interrupt as some sort of signal to the thread then I would instead set some volatile boolean flag.
In terms of best practice when catching InterruptedException, typically I do:
try {
...
} catch(InterruptedException e){
// a good practice to re-enable the interrupt flag on the thread
Thread.currentThread().interrupt();
// in your case you probably should interrupt the Thread a in turn
a.interrupt();
// quit the thread
return;
}
Since catching the InterruptedException clears the interrupt flag for the thread, it is always a good idea to re-enable the interrupt flag in the catch block.
In various example I have seen, even in text-books, the exception is ignored.
Indeed. It is very bad practice to ignore any exception but it happens all of the time. Don't give into the dark forces!
can it be the case that Thread B may still actually be runnable/running?
Thread B can certainly still be running. It is the main thread that is calling the join() that has been interrupted.
Related
Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most 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. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged
Say i've got the following code:
public void run(){
while (true){
function1();
...
functionN();
}
}
And i wanna exit 'gracefully' - Which means for me that once i sent a shutdown signal and currently the thread is at functionK(), The thread will 'break' the loop and exit run.
So i've tried using Thread.interrupt() like this:
public void run(){
while (true){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
But this doesn't work - The thread continutes to run endlessly even with interrupt flag on.
Just for the record:
public void run(){
while (!thread.isInterrupted()){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
Stops the loop, But doesn't help me. Since each function does something that might take several minutes and there are a lot of different function so checking before each function whether interrupted flag is one might be costly (Especially since most of the times the application runs smoothly).
I wonder whether there is a special mechanism i can use for that kind of problem.
The API documentation is very clear about this:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
So you can only rely on this exception if you're waiting for object monitors. There are a couple of other exceptions thrown by certain I/O operations but if you don't use them either, there is no other option than to check the interrupted() flag.
What you can do though is to re-organise your code: if you've got N methods that are called one after the other, is it not possible to abstract them out into a loop? More often than not it is possible to find a way to refactor code to support interruption, the exact way depends on your actual scenario. My first question would be: why does a single method run for minutes? That sounds a bit fishy (though it may be justified).
Either way, interruptibility isn't something that comes for free, you have to actively design interruption points if you want your code to be more responsive to interruption than the length of the main loop.
One more thing though: checking the interrupted() flag is most definitely NOT costly. Not when you spend minutes in your main loop, and it's a lot cheaper than constructing and handling an exception. I'd go as far as to say that you'll find very few things faster than a call to Thread.isInterrupted().
Actually if you are doing CPU bound work in your methods, you have to check for Thread.interrupted() by yourself and throw InterruptedException yourself. Java won't magically do it for you, unless you park at some specifically designed spaces, such as Semaphore.wait() etc.
Your second example will keep looping after the interrupt. This is because InterruptedException doesn't actually mean that the Thread's interrupted flag is set; in fact, you don't need to check it at all.
To fix this, you can simply re-interrupt the thread (to allow callers to know that the thread was interrupted), and then break:
public void run(){
while (true) {
try {
function1();
//...
functionN();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
}
As stated in the book "Java concurrency in Practice" :"Java does not provide any mechanism for safely forcing a thread to stop what is doing", so you must implement something on your side. checking the interrupted flag and handling the InterruptedException is the best way to manage thread cancellation.
If one of you function1()...functionN() is in the middle of a database transaction or a HTTP call is up to your program to handle the cancellation; you can wait until to n seconds and save the current state or cancel the transaction and roolback, the action to perform is dictated by your application logic.
I thought that the currently executing Thread will be stooped if the exception is thrown. Bu when I was going throught a java test a came across with the question:
Under which conditions will a currently executing thread stop?
When an interrupted exception occurs.
When a thread of higher priority is ready (becomes runnable).
When the thread creates a new thread.
When the stop() method is called.
A. 1 and 3
B. 2 and 4
C. 1 and 4
D. 2 and 3
The right answer was B, but what then happens if the exception is thrown? I thought the thread is terminating.
The right answer was B
No it wasn't. None of the answers given is correct.
but what then happens if the exception is thrown? I thought the thread is terminating.
No. The thread catches InterruptedException from whatever method it was calling that can throw it, for example Thread.sleep(). If it doesn't call such a method, nothing happens at all.
When a method throws InterruptedException, it is telling that it is a blocking method and that it will make an attempt to unblock and return early -- if you ask nicely.
When you try to interrupt a thread by calling interrupt() on the thread instance, it merely sends a signal. It depends on the actual thread to respond to that signal. Methods like Thread.sleep() and Object.wait() can look for this signal and make an attempt to stop what it is doing and return early and indicate its early return by throwing InterruptedException. So it's usually an acknowledgement from some blocking methods to the interrupt() request sent by some other thread.
Thread t = new Thread(() -> {
try {
Thread.sleep(5000); // Thread.sleep() allows a cancellation mechanism
} catch (Exception e) {
System.out.println("interrupted by some one else from outside");
}
});
t.start();
try {
t.interrupt();
t.join(); // waiting for the thread to finish its execution
System.out.println("back in main");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
Output :
interrupted by some one else from outside
back in main
But if you have thread like this
Thread t = new Thread(() -> {
try {
for(int i=0;i<1_000_000;i++){
System.out.println(i);
}
} catch (Exception e) {
System.out.println("interrupted by some one else from outside");
}
});
Calling interrupt() on above thread will not do anything useful because we're not looking for the signal, so thread will print all numbers and join the main thread as if nobody ever asked it to stop doing what it is doing.
In case you want to learn more about this InterruptedException, I highly recommend thisBrian Goetz's article from IBM Developer Works
A thread, t, will stop if some other thread calls t.stop(), but please don't ever do that! One thread should never force another thread to do anything. Threads should always cooperate. Any program that calls t.stop() is very likely to contain bugs that you won't be able to fix without getting rid of the stop() call.
A thread will terminate (which is a kind of stop, right?) if some external process kills the JVM.
A daemon thread will terminate if the JVM shuts down because there are no non-daemon threads left to keep it alive.
A thread may stop or terminate because of the action of an attached debugger.
The only other reason why a thread will stop (and terminate) is if its run() method completes. A method can either complete normally by returning, or it can terminate abnormally (i.e., an exception is thrown and not caught within the method call.) A thread will terminate if its run() method completes in either way.
An InterruptedException doesn't affect a thread any differently from any other exception. If the thread catches the exception, then the thread will continue to run, but if no method in the thread catches it, then the thread's run() method will abnormally complete, and the thread will terminate (stop).
I have implemented a connection check thread. When I have created a heavy traffic I have realized that there are many "ConnWatchdogThread" instances.
I think "continue" statement triggers the interrupted thread live and in that case new "ConnWatchdogThread" is created. If so how this happen? How thread is interrupted?
private class ConnWatchdog extends Thread {
public ConnWatchdog(){
setName("ConnWatchdogThread");
}
private void checkConnections() {
//connection check
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(checkPeriod);
} catch (InterruptedException e) {
// e.prinstackTrace()
continue;
}
try {
this.checkConnections();
} catch (Throwable t) {
}
}
}
}
Interruption happens when the interrupt method on the thread is called. It's not shown in your example what is doing the interrupting. Here's an example of using interrupt.
The continue advances control to the next iteration of the loop. So when something calls interrupt on your thread while it's sleeping, it bails out of the sleep (clearing the interrupt flag), then the continue sends it back to the top of the loop and it goes to sleep again, which seems pointless.
Nothing in the code shown causes a new thread to be created.
It would be more normal to use the interruption to exit the while loop and cause the thread to terminate. Using interruption for things other than thread-cancellation is not recommended (Java Concurrency in Practice, 7.1, page 138):
There is nothing in the API or language specification that ties interruption to any specific cancellation semantics, but in practice, using interruption for anything but cancellation is fragile and difficult to sustain in larger applications.
The only way to create a new Thread is with new Thread(...). Your continue is causing interrupt to be ignored and for it to sleep a little longer.
Interrupt is a special flag (but basically still just a flag) When you interrupt() a Thread it will cause some methods to throw an InterruptedException even if they are blocking. Once triggered the flag is reset.
It is generally a bad idea to ignore exception/error thrown esp in code which is not working perfectly.
Your not showing the code that uses this class. No way to say what is making the instances. Continue wont do it. In fact can remove continue from your code in the ConnWatchdog first try-catch and it will work just fine.
Post your code that is calling ConnWatchdog / instantiating it to see full picture. Is that in a loop?
When does Java's Thread.sleep throw InterruptedException? Is it safe to ignore it? I am not doing any multithreading. I just want to wait for a few seconds before retrying some operation.
You should generally NOT ignore the exception. Take a look at the following paper:
Don't swallow interrupts
Sometimes throwing InterruptedException is
not an option, such as when a task defined by Runnable calls an
interruptible method. In this case, you can't rethrow
InterruptedException, but you also do not want to do nothing. When a
blocking method detects interruption and throws InterruptedException,
it clears the interrupted status. If you catch InterruptedException
but cannot rethrow it, you should preserve evidence that the
interruption occurred so that code higher up on the call stack can
learn of the interruption and respond to it if it wants to. This task
is accomplished by calling interrupt() to "reinterrupt" the current
thread, as shown in Listing 3. At the very least, whenever you catch
InterruptedException and don't rethrow it, reinterrupt the current
thread before returning.
public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
}
From Don't swallow interrupts
See the entire paper here:
http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-
If an InterruptedException is thrown it means that something wants to interrupt (usually terminate) that thread. This is triggered by a call to the threads interrupt() method. The wait method detects that and throws an InterruptedException so the catch code can handle the request for termination immediately and does not have to wait till the specified time is up.
If you use it in a single-threaded app (and also in some multi-threaded apps), that exception will never be triggered. Ignoring it by having an empty catch clause I would not recommend. The throwing of the InterruptedException clears the interrupted state of the thread, so if not handled properly that info gets lost. Therefore I would propose to run:
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// code for stopping current task so thread stops
}
Which sets that state again. After that, finish execution. This would be correct behaviour, even tough never used.
What might be better is to add this:
} catch (InterruptedException e) {
throw new RuntimeException("Unexpected interrupt", e);
}
...statement to the catch block. That basically means that it must never happen. So if the code is re-used in an environment where it might happen it will complain about it.
The Java Specialists newsletter (which I can unreservedly recommend) had an interesting article on this, and how to handle the InterruptedException. It's well worth reading and digesting.
Methods like sleep() and wait() of class Thread might throw an InterruptedException. This will happen if some other thread wanted to interrupt the thread that is waiting or sleeping.
A solid and easy way to handle it in single threaded code would be to catch it and retrow it in a RuntimeException, to avoid the need to declare it for every method.
From the docs:
An InterruptedException is thrown when a thread is waiting,
sleeping, or otherwise occupied, and the thread is interrupted, either
before or during the activity.
In other words, InterruptedException occurs when some code has called the interrupt() method on a specific thread. It's a checked exception, and many blocking operations in Java can throw it.
The purpose of the interrupt system is to provide a alternative workflow for allowing threads to interrupt tasks in other threads. An interruption necessarily may not interrupt a running thread but it can also request that the thread interrupt itself at the next convenient opportunity.
Threads may get blocked for several reasons:
waiting to wake up from a Thread.sleep()
waiting to acquire a lock, waiting for I/O completion
waiting for the result of a computation in another thread, etc.
The InterruptedException is usually thrown by all blocking methods so that it can be handled and the corrective action can be performed.
However, in majority of the cases as our code is a part of a Runnable, in this situation, we must catch it and restore the status.
There are a handfull of methods in Java that throws InterruptedException. Some examples are:
Object class:
Thread.sleep()
Thread.join()
wait()
BlockingQueue:
put()
take()
From personal experience, I simply changed thread.sleep() into this.sleep()
The InterruptedException is usually thrown when a sleep is interrupted.