How exactly does Thread.interrupt() and Thread.interrupted() work? [duplicate] - java

This question already has answers here:
What does java.lang.Thread.interrupt() do?
(10 answers)
Closed 9 years ago.
I am not clear regarding these two methods from the perspective of setting the status of the thread.
Java Docs say that Thread.interrupt() sets the threads interrupt status flag and calling the Thread.interrupted() method gives the status of the thread and clears the flag.
When this comes to use in real scenarios..??

When some other thread calls Thread.interrupt() the method sets Thread's interrupt status flag (initially false) to true. If the Thread is in blocking method like Thread.sleep(), Thread.join() or Object.wait() it unblocks and throws an InterruptedException.
Thread.interrupted() is a static method which can be use to check the current value of interrupt status flag, true or false. It also clears the interrupt status , setting the flag to false. That is calling it twice in a row may likely return false the second time even if it returned true the first time (unless the thread were interrupted again, setting the interrupt status flag to true after the first call)
Note a third method Thread.isInterrupted() which can check the interrupt status without resetting.
Typical use cases:
Break exceptionally from a blocking operation
Determine if it is desired to continue a long sequence of instructions at some logical save/stop point
Determine if it is desired to continue a sequence of instructions prior to beginning a long running task
Stop executing an iterative process that would otherwise continue into perpetuity (while(true) is bad, while(!Thread.interrupted()) is better)

You can use Thread.interrupt() to tell a thread to stop. When that thread performs a some blocking operations or checks the flag it trigger it to throw an InterruptedException to either wake up the thread or stop it.
While the purpose of interrupt() is usually to stop a thread, it doesn't mean it will. The interrupt can be ignored for long periods of time or completely ignored. If it triggers an InterruptedException this can be caught and loggged (or ignored) rather than stopping the thread.
Note: For threads in an ExecutorService, interrupting a task interrupts the thread and the ExecutorService catches this by design and doesn't shutdown the thread.

Related

What is the reason of clearing of thread's interrupt status by Thread.interrupted()? [duplicate]

This question already has answers here:
Why do InterruptedExceptions clear a thread's interrupted status?
(4 answers)
Closed 2 years ago.
In many sources I found that Thread.interrupted() method clears interrupt status of thread, but in none of them there was explanation of the reason why this method works exactly in this way.
I still feel confused a little because of lack of understanding of this reason and lack of understating of what problem designers of java tried to solve by clearing interrupt status.
I will appreciate very much if someone could explain that and show some example.
The idea behind thread interruption is that one thread may signal another to request that it interrupt is regular processing to divert its attention to some thread-specific special action. What a thread actually does in response depends entirely on the code running in that thread.
There are two main ways in which a Thread can determine whether it has been interrupted:
Several Thread and Object methods will throw an InterruptedException if invoked in a thread whose interrupted status is set, or if a thread is interrupted while the method is executing. The interrupted status is cleared in this event, presumably because the exception is considered adequate notice of the interruption.
Code running in the thread can invoke Thread.interrupted() or Thread.currentThread().isInterrupted() to proactively test for an interrupt. The former also resets the interrupted status; the latter does not, likely because it is an instance method -- interrupts must not be lost in the event that one thread calls the isInterrupted() method of a different one.
The techniques that cause the interrupt status to be reset do so in order that the thread is able to handle subsequent interruptions. The key point here is perhaps that thread interruption is not intended to necessarily cause the interrupted thread to shut down (although that is indeed one response that a thread can make). It is a more general mechanism.
From jdoc
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate
and
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
So Thread.interrupted clears the flag because it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
Explanation https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

What does Thread.interrupt() do if the thread isn't blocked?

The JavaDoc for Thread says a Thread.interrupt() interrupts a thread as follows:
Threads blocked in one of Object's wait() methods or one of Thread's
join() or sleep() methods will be woken up, their interrupt status
will be cleared, and they receive an InterruptedException.
Threads blocked in an I/O operation of an InterruptibleChannel will have their interrupt status set and receive an ClosedByInterruptException. Also, the channel will be closed.
Threads blocked in a Selector will have their interrupt status set and return immediately. They don't receive an exception in this case.
What if the thread doesn't meet any of the above criteria? Is it killed or does it continue running or what?
Thanks in advance...
If the interrupted thread does not check Thread.isInterrupted() and does something about it, then the call to Thread.interrupt() on an unblocked thread does effectively nothing other than simply setting the flag. It's the thread implementer's job to properly check the Thread's status with Thread.isInterrupted() and take the appropriate action.
Some things to read from JLS
17.2.3. Interruptions
Interruption actions occur upon invocation of Thread.interrupt, as
well as methods defined to invoke it in turn, such as
ThreadGroup.interrupt.
Let t be the thread invoking u.interrupt, for some thread u, where t
and u may be the same. This action causes u's interruption status to
be set to true.
Additionally, if there exists some object m whose wait set contains u,
then u is removed from m's wait set. This enables u to resume in a
wait action, in which case this wait will, after re-locking m's
monitor, throw InterruptedException.
Invocations of Thread.isInterrupted can determine a thread's
interruption status. The static method Thread.interrupted may be
invoked by a thread to observe and clear its own interruption status.
And from Thread.interrupt() Javadoc
public void interrupt()
Interrupts this thread. Unless the current
thread is interrupting itself, which is always permitted, the
checkAccess method of this thread is invoked, which may cause a
SecurityException to be thrown.
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 interruptible
channel 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.
Interrupting a thread that is not alive need not have any effect.
Summary:
If a Thread is in wait, sleep, join or something else which put it in a wait state it will just throw the InterruptedException to notify that some thread wants that he should stop what he is doing and death.
If it's not in one of previous state it will just set a flag (called interrupt status). As you can understand it will do nothing to avoid some errors caused by a early interrupted thread which could lead your objects to be in a inconsistent state (you cannot know what it's doing).
This flag is used by the thread to know if someone asks to him to stop his work, it's up to the programmer to choose if stop the thread or not (you are free to ignore it.)
Important: Methods like wait, sleep etc (said above) will clear the flag when throw the exception. It's important if you do something like while(!Thread.isInterrupted()) to remember this.
If you need, you can know the current flag status using isInterrupted or interrupted
The only differences between the two that interrupted will reset the flag, while isInterrupted not.
Another great reading, here.
(p.s i hope to link the right JLS section, i will search more.)

Understanding the usage of Thread.interrupt()

I am reading Interrupts from Oracle Docs. I am unable to figure out the following
part. It states that
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received. For example:
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
I am scratching my head to understand, what does it mean by What if a thread goes a long
time without invoking a method that throws InterruptedException? Secondly, what is the usage
of Thread.interrupted(), it is a way, that thread can send a interrupt to itself? Whats the
practical usage of this scenario? Thanks.
This is a technique to keep the thread available for interruption.
Thread.interrupted() : checks whether present thread (itself) was interrupted by some other thread and clears the interrupted status flag. So it asks itself whether I was interrupted by someone to exit from what I was doing while I was performing a BIG BIG task and not listening to someone.
Imagine what would have happened if that thing was not done.
Suppose one iteration of heavyCrunch() takes 1 min worth of time. So n iterations will take n minutes.
Now suppose after starting the program you decide that you want to exit the program and terminate the program gracefully. So you interrupt the thread that is doing the heavy crunch.
BUT the thread is unknown of the fact that you have interrupted it as it is not checking for the interrupt status. So the program will not end until N Minutes have not completed and you will have to wait for long time.
So to gracefully terminate the thread, it should always keep checking the interrupt status to respond if someone else has requested interruption.
If you interrupt the thread running this code
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
}
it will only set interrupted status in the thread but it will not stop it
Thread.interrupted tests if interrupted status is set (and clears it) so by adding
if (Thread.interrupted()) {
return;
}
to the loop you make the code interruptible
Besides the fact that the phrase
What if a thread goes a long time without invoking a method that throws InterruptedException?
is deeply unclear, i suppose they mean the following:
Usually, if you have a thread that does some work in a while(true) loop, that is, a thread that does not terminate for a long time, you will probably place ANY function that throws InterruptedException in that thread (i.e. Thread.sleep(), a socket read, or anything!). This way, when your thread will be noticed an Interruption, one of those functions will catch it and you will be able to QUIT what you are doing in the thread (the thread does not just magically terminate itself).
Here comes what the phrase wanted to say:
WHAT IF YOU DO NOT WANT/HAVE to use these functions? Then you should use Thread.interrupted() to check whether you should QUIT doing what the thread is doing in the same way you would do if you catched an InterruptedException.
I hope this was clearer than the doc...
You can use interrupted() stop nicely any long running thread by intrrup thread somewhere and check the condition by Thread.interrupted() and based on this come out of run method.
Let say you one thread is blocked on some monitor and somewhere else that thread got interrupted which inturn will throw InterruptedExceptionand can come out of block state with interrupted status true.
I think interrupt is the best way to achieve stop long running task because an interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
May help you.
interrupt() sets from outside a flag in the object that can then be queried periodically by Interrupted() in the run() method.
I am scratching my head to understand, what does it mean by What if a thread goes a long time without invoking a method that throws InterruptedException?
A: If other thread call the interupt() method of this thread, and 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. Otherwise, just set the interrupt status.
Secondly, what is the usage of Thread.interrupted(), it is a way, that thread can send an interrupt to itself? What's the practical usage of this scenario?
A: Thread.interrupted() is use to detect current thread's interrupt status, return true if it's set and then clear the status. You check this in order to respond to other thread's interrupt call, such as throw an InterruptedException and exit the thread or just exit.

Stopping a recursive function in JAVA (from within a thread)

I think that this question has been brought up a few times in the past, but this is a little different and i could not find an appropriate answer anywhere.
I have a thread which calls (inside run()) another recursive function. This is actually a game engine and the recursive function is MiniMax.
The problem is, that when the user wants to Resign a game in the middle of the calculation, or even Undo a move, then how should I stop this function?
I cannot interrupt the thread with a boolean, since if the call to Minimax has already been made, then the program is inside this function and the thread will not check the interruption condition in order to termintate, calling interrupt() also does not work.
How do I stop such a function?
Calling Thread.interrupt() will throw InterruptedException at any wait() or sleep() that you call from the thread proccess, also remember to check isInterrupted() to "not do things".
When InterrupedException is thrown from sleep/wait (or join) the interrupted status is cleared, and a call for isInterruped() will return false, so remember to interrupt() the Thread after the Exception.
Also, using boolean interrupted() instead of isInterrupted() does clear interruped status, and a double check with interrupted may result in true following by false if not interrupted again between calls.
PS: One more suggestion, if interrupt is not enough, you can has a Queue that you can send messages and consume it from the running thread and interpret the value to stop the proccess (note that it's not a static flag, it's a Queue or something similar).
This solution is actually getting aroung the problem, not too elegant, but quite creative. I found it in the source code of junit's FailOnTimeout statement. What they do is to wrap a Callable in a FutureTask then launch it using a thread. Then they call FutureTask.get(long timeout, TimeUnit unit) which returns the result or throws a TimeoutException if timeout units passed and lets the thread run as long as it wants. I think the same idea could be used here as well.

Interrupting a thread while it is running; what is the impact of the next interruption?

Let's assume thread t1 is running (i.e. not in a sleep, wait or join state). Another thread t2 interrupts t1. The Javadoc says t1's interrupted status will be set.
Let's assume t1 falls into sleep, wait or join status later. What happens?
i) Is thread t1 automatically raised with an InterruptedException since it had an interrupted status?
Let's assume t1 is still into a sleep, wait or join state. Let's imagine t2 interrupts t1 again:
ii) Is thread t1 raised with an InterruptedExecution or does it need to clear its interruption status with a call to interrupted() first?
Is there an official Java position on this one? Thanks.
In the first case ("i"), yes, the sleeping thread will get popped out of its call to Thread#sleep() by way of an InterruptedException being thrown. At this point, the thread's status flag represented by Thread#isInterrupted() will be cleared; calling Thread#isInterrupted() would return false. Since the InterruptedException is in flight, the message has been sent to all transitive callers.
It's then the callers' responsibility to catch that exception and do one of two things:
either exit the current thread, or
call Thread#interrupt() on the current thread (that is, Thread.currentThread().interrupt())
When you say that thread "t1" is "still in a sleep, wait, or join state," the only way it could be so after its initial call to Thread#sleep() exited via InterruptedException is if it caught the exception, ignored it, and called on some blocking method like Thread.sleep() again before thread "t2" has a chance to interrupt it a second time.
If thread "t2" were to interrupt thread "t1" again while "t1" is currently blocked on an interruptible method call, "t1"'s call will again exit with an InterruptedException. Otherwise, the thread's interruption flag will be set for later detection.
Every time one calls Thread#interrupt(), the the interruption status of that target thread will be set to "true," meaning the thread has been interrupted since its interruption status was last cleared. The next time that the interrupted thread attempts to make a blocking call to an interruptible method, the thread's interruption status will be cleared and the method will throw InterruptedException.
Note that clearing the interruption status like that does not lose information so long as the clearing is immediately followed by throwing InterruptedException. A thrown InterruptedException is best interpreted as, "This thread had its interruption status set at some point prior, and now it's your responsibility to react and, usually, to warn subsequent callers of the intended interruption." You achieve the latter objective by calling Thread#interrupt() after catching InterruptedException, restoring the interruption status for others to see.
See the book Java Concurrency in Practice for a more authoritative description of this protocol.
Checking the interrupted state of a thread clears the state flag; that is to say, the code that raises an InterruptedException is clearing the state, as your own code that manually samples the state.

Categories

Resources