Understanding wait and interrupt from Java Language Specification - java

I was trying to understand threads and locks from Java Language Specifications chapter 17. It says:
(Quote 1)
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.
I believe this corresponds to sentence "If none of the previous conditions hold then this thread's interrupt status will be set." from the Thread.interrupt() doc.
Q1. Am I right?
It further says:
(Quote 2)
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.
I believe this correspond to the sentence "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." from Thread.interrupt() doc.
Q2. Am I right?
Q3. What does it mean by "enables u to resume in a wait action, in which case this wait will, after re-locking m's monitor, throw InterruptedException"
It further says:
(Quote 3)
If a thread is both notified and interrupted while waiting, it may either:
return normally from wait, while still having a pending interrupt (in other words, a call to Thread.interrupted would return true)
return from wait by throwing an InterruptedException
The thread may not reset its interrupt status and return normally from the call to wait
Q4. Does the last statement correspond to the first bullet point?
(Quote 4)
Similarly, notifications cannot be lost due to interrupts. Assume that a set s`` of threads is in the wait set of an object m, and another thread performs a notify on m. Then either:
at least one thread in s must return normally from wait, or
all of the threads in s must exit wait by throwing InterruptedException
Note that if a thread is both interrupted and woken via notify, and that thread returns from wait by throwing an InterruptedException, then some other thread in the wait set must be notified.
Q5. Does above last sentence correspond to 2nd bullet points from 3rd quote?
Q6. How / why 2nd bullet point holds, specifically "all"?
I don't get logic behind following sentence from the Thread.interrupt() doc:
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.
Q7. Does it mean, by getting out of wait / sleep / join, the reaction or response to interrupt() is complete and hence clear the interrupt and indicate that the interrupt and its response happened by raising InterruptedException?

I'm only going to attempt to answer one of your several questions:
Q3. What does it mean by "enables u to resume in a wait action, in which case this wait will, after re-locking m's monitor, throw InterruptedException"
Piece by piece:
enables u to resume
Just what it says on the tin: Thread u, which was blocked in a call to m.wait(), will stop waiting for some other thread to call m.notify().
...after re-locking m's monitor...
Because m.wait() must never return without first re-locking the monitor. It doesn't matter whether m.wait() returns normally or abnormally*. The reason is, the handler for the exception could be inside the synchronized (m) block, and a thread must never execute inside a synchronized block without holding the monitor.
...throw InterruptedException
Again, just what it says on the tin: The m.wait() call will throw an exception instead of returning normally.
* When a function throws an exception, that event is called an "abnormal return" in some documentation contexts.

Related

If wait() throws an InterruptedException, does the thread wait until it acquires the object's monitor?

For example:
public synchronized Object get() {
while (result == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
// Do we own the monitor of this object?
}
}
return result;
}
When e.printStackTrace() executes, are we guaranteed to own the object's monitor?
The reference says that when wait() returns after a notify() or notifyAll() call, the thread waits until it acquires the object's monitor. But what about the case when wait() throws an exception?
By the time wait returns (including the case where it throws InterruptedException) the thread has to have the monitor, otherwise it can't be executing in that synchronized method. The thread has to acquire the monitor before it can leave the wait method. Then once it's out of the wait method the thread has the monitor, and releases it when the thread leaves the method.
It's better here to throw the InterruptedException to the caller instead of eating it. Your goal here is to get out quickly and let the caller know an interruption happened so it can wrap things up. Eating it here also seems to mean you go back through the while loop again. Interruption is used by java.util.concurrent to implement cancellation, especially if you make use of java.util.concurrent tools it makes sense to write code that is compatible with them.
Yes. In fact, this InterruptedException is thrown after re-acquiring the monitor.
See wait in jls:
Let thread t be the thread executing the wait method on object m, and
let n be the number of lock actions by t on m that have not been
matched by unlock actions. One of the following actions occurs:
If n is zero (i.e., thread t does not already possess the lock for
target m), then an IllegalMonitorStateException is thrown.
If this is a timed wait and the nanosecs argument is not in the range
of 0-999999 or the millisecs argument is negative, then an
IllegalArgumentException is thrown.
If thread t is interrupted, then an InterruptedException is thrown and
t's interruption status is set to false.
Otherwise, the following sequence occurs:
Thread t is added to the wait set of object m, and performs n unlock
actions on m.
Thread t does not execute any further instructions until it has been
removed from m's wait set. The thread may be removed from the wait set
due to any one of the following actions, and will resume sometime
afterward:
A notify action being performed on m in which t is selected for
removal from the wait set.
A notifyAll action being performed on m.
An interrupt action being performed on t.
If this is a timed wait, an internal action removing t from m's wait
set that occurs after at least millisecs milliseconds plus nanosecs
nanoseconds elapse since the beginning of this wait action.
An internal action by the implementation. Implementations are
permitted, although not encouraged, to perform "spurious wake-ups",
that is, to remove threads from wait sets and thus enable resumption
without explicit instructions to do so.
Thread t performs n lock actions on m.
If thread t was removed from m's wait set in step 2 due to an
interrupt, then t's interruption status is set to false and the wait
method throws InterruptedException.

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.

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

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