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