Understanding the usage of Thread.interrupt() - java

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.

Related

How the main thread sleep/interrupt works in following code

How the second loop actually interrupts the sleeping main thread, and first does not??
My understanding is after Thread.sleep(3000), the code Thread.currentThread().interrupt() will be executed after 3 seconds.
Can anyone explain how it actually works
for (int i = 0; i < 2; i++) {
try {
System.out.println("loop : " + i);
Thread.sleep(3000);
System.out.println("Woke up");
Thread.currentThread().interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
loop : 0
Woke up
loop : 1
java.lang.InterruptedException: sleep interrupted
exception loop:1
at java.base/java.lang.Thread.sleep(Native Method)
at multithreadings.Mainclass.main(Mainclass.java:13)
Interruption is a polite request to stop: a Thread is under no obligation to stop.
It's like the Robin Williams joke about what police in the UK say when you commit a crime:
Stop! Or I'll say stop again!
Also, interrupting a thread doesn't cause an InterruptedException to be thrown: it merely sets a flag on the thread. If something (like Thread.sleep) checks this flag, and finds that it is set, it may then throw an InterruptedException; but the flag and exception are two orthogonal ways of indicating interruption.
As such:
On the first execution, you sleep for 3 seconds, then set the interrupted flag, and the loop body finishes normally.
On the second execution, you ask to sleep for 3 seconds, but Thread.sleep detects the interrupted flag, and throws the exception.
There is a single thread involved in the code you posted. This thread executes a loop. At the first iteration, the thread interrupts itself. Interrupting doesn't mean "stop executing immediately". It means: "please, I would like you to stop running when you can".
A thread that wants to respect interruption requests can do it in two ways:
It regularly checks if it has been interrupted, and if it's the case, then it stops executing (by breaking out of a loop or returning, for example)
It calls a blocking method such as sleep(), which will throw an InterruptedException if the thread has been interrupted or is being interrupted.
What happens is the second case. A request for interruption is done in the first iteration, after the call to sleep(). The thread continues running, and at the second iteration, it calls sleep(), which throws en InterruptedException because the thread has been interrupted before.
In Java, one thread cannot stop the other thread. A thread can only request the other thread to stop. The request is made in the form of an interruption. Calling the interrupt() method on an instance of a Thread sets the interrupt status state as true on the instance.
All blocking methods respond to interruption by throwing InterruptedException once the interrupt status is set to true. , if you want to check more in detail, please read the below article. See how Thread Interruption works in Java.
Read the documentation, i.e. the javadoc of interrupt():
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, ...
If this thread is blocked ...
If this thread is blocked ...
If this thread is blocked ...
If none of the previous conditions hold then this thread's interrupt status will be set.
and sleep(long millis):
Throws InterruptedException if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Since the thread has already interrupted itself on the second iteration of the loop, thereby setting it's own interrupted status, the sleep(...) method is immediately interrupted.

What is the difference between wait/notify and wait/interrupt?

synchronized (Foo.class) {
while (someCondition) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
It seems that this thread both wakes when some other thread call interrupt() or notify() on this thread. Are there any differences between the two?
--EDIT--
I know one is for notifying an object, the other interrupts a thread. But both of these lead to the same consequence, that is, this thread is waken up, so what I want to ask is how these 2 situations' consequences are different from each other.
When a thread calls notify on some monitor, it wakes up a single thread that's waiting on that monitor, but which thread gets woken is decided by the scheduler. (Alternatively a thread can call notifyAll, which wakes up all the threads waiting for that monitor, then they all contend for the monitor, then the losers go back to waiting.) That's why the target of the call is different, the notification is made to the monitor, which tells the scheduler to pick a thread to wake up.
Unlike notify, interruption targets a specific thread. And interruption does not require that the interrupted thread be waiting on a monitor. For a thread to call wait on a monitor it has to have acquired that monitor first, then wait releases that monitor until the thread is done waiting or is interrupted.
Oracle's recommendation is to use interruption only for cancellation. Also the classes in java.util.concurrent are designed to use interrupt for cancellation.
In your example interruption won't be very effective, because control doesn't leave the while loop, the thread still has to check the condition it's waiting on, and there's no check in the while loop condition for whether the interrupt flag is set. It's likely the thread that's interrupted will go right back to waiting.
In order to make this code quit once it's interrupted, rather then return to waiting, add a check for the interrupted flag status to the loop condition, and have the catch block set the interrupt flag (which gets reset when the exception is thrown):
synchronized (Foo.class) {
while (someCondition && !Thread.currentThread().isInterrupted()) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Basically, you are not looking for a text book difference but difference in their uses cases.
As folks have already pointed out, waking up the thread is not the only consequence but calling t1.interrupt() from Thread t2 for t1 will cause an InterruptedException in thread t1 and that is a big difference between Object.notify() and Thread.interrupt().
You should understand that its method Object.wait() which throws checked InterruptedException and forces you to handle it. Object.wait.
InterruptedException - if any thread interrupted the current thread
before or while the current thread was waiting for a notification. The
interrupted status of the current thread is cleared when this
exception is thrown.
Then you should consult this question to get an idea about handling this exception.
Difference between the two lies in the fact that one is for inter thread communication for usual logical programing stuff ( wait & notify ) and other one ( interrupt) is for preemptive thread cancellation / termination even in cases of blocking operations. You have to note that Java doesn't provide any mechanism to preemptively cancel a thread so you have to use interrupt mechanism for that purpose ( Obviously, if that is needed in your case. You might very well ignore this Exception if not applicable in your case).
Java doesn't restrict your actions after InterruptedException and you can do anything you want but using it for things other than implementing Thread Cancellation Policy is not advised. Thread Cancellation Policy is often ignored and less discussed area when programmers write multi threaded programs and that is why you might be finding it difficult to understand the use case.
What does an API method like BlockingQueue.put(..) is trying to tell you by throwing InterruptedException is that even its blocking operation can be preemptively terminated. Its not necessary that all blocking API methods will provide you that facility.
Cancellation/Termination of a thread using Thread.interrupt() is not a forceful but cooperative mechanism and is just a request not an order.
Your use of e.printStackTrace(); is strongly discouraged since this is usually not an error, if intention is to log it as an error.
Hope it helps !!
Wait method is used to suspend a current thread on an object.
Wait method is not from thread class but from java.lang.Object
Notify method is used to wake the thread waiting on the object.
Notify method is not from thread class but from java.lang.Object.
Interrupt method is used to to indicate the current thread that is
should stop current job execution and can start other job.
Interrupt method is from thread class.
Let see the real life example:
Consider Telephone as Object , Person as Thread.
Suppose for instance A person is using Telephone and B person also wants to use the telephone but as A person i.e (Thread 1) is busy using it unless the work is done acquires a lock on telephone Object now B i.e(Thread 2) tries to use Telephone but as A has acquired lock on it B it goes into wait state until lock is released.
If Telephone object calls wait method it will restrict current thread
which want to use Telephone and it will go into wait state.
If Telephone object calls notify it will signal the thread waiting on
it to acquire lock and proceed with the intended work.
If Person A(Thread 1) is using Telephone object and is in some task
but interrupt method is called then A will be signaled to stop with
current task and may need to do some other task assigned.

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.)

Interrupted Exception occurrence reason

While going through the javadoc for the notifyAll() method under Object class came through the following lines:
If the current thread is interrupted by any thread before or while it is waiting, then an
InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.
The point is:
the current thread is interrupted while it is waiting
What does this means? Can a thread be interrupted while it is waiting?
If yes, why? What is the use of it?
The meaning of "thread getting interrupted" in Java means that the thread's interrupted flag has been set, nothing more. However, most methods of the JDK which make the thread wait will immediately find out about this and exit the wait state, throwing an InterruptedException. Such is the case with the methods you have been reading about.
A thread can be interrupted while waiting if another thread calls:
waitingThread.interrupt();
This can happen if you do it yourself of course but also if you use a framework to manage your threads, typically an executor service, and call some of the methods that interrupt the underlying threads (e.g. shutdownNow or if you call future.cancel(true); on the Future returned by the submit method).
The interruption mechanism is how Java enables one thread to tell another one to stop what it is doing and is therefore extremely useful.

Why does Threads in BLOCKED state do not get interrupted?

I am working on multithreading in java.
Want to understand if a Thread is in BLOCKED state why it cant be interrupted? And why the thread can be interrupted only if it is in WAIT state? Basically, why do we need two Thread states one which can be interrupted and the other which cant be interrupted?
This question might be very basic but, I am trying to understand things rather than just remembering them.
One assumes that you mean cause the thread to stop its current operation and throw an InterruptedException? A thread interrupt in Java is just a flag. You can call interrupt() just fine on a BLOCKED thread and that flag will be seen next time code checks for it.
The principle problem with implementing such a functionality is, how is a keyword (synchronized) supposed to throw an exception? InterruptedException is a checked exception, it would not be a useful exercise to have to declare every synchronized method (and block) in the language with throws InterruptedException!
An interrupt is a communication tool, it's generally for letting a thread know about a system state it needs to check on. The name is a legacy carry over/upward from flags set within hardware to let microprocessors know about a particular state (such as new values set on some input pins) that needs to be examined. Do not read too much into the name "interrupt" and think it's meant to be a tool for breaking the flow of the program within another thread. It is not. Hence even the methods that do throw an exception declare it as checked, the other thread is free to ignore it and resume waiting if it wants. Being able to arbitrarily break another thread's BLOCKED state would break the program flow, which is not the purpose.
Blocked Threads can receive Interrupts. You may have to check Thread.currentThread().interrupted() to see whether Thread got interrupt when it was waiting to acquire any resource.
See Also Lock::lockInterruptibly()
A blocked thread can be interrupted. Here is how interrupt is called on a thread depending on which state it is. From javadocs:
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.
Throws: SecurityException - if the current thread cannot modify this
thread

Categories

Resources