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.)
Related
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.
JLS 17.2.4:
If a thread is both notified and interrupted while waiting, it may
either:
[...]
Could you give an example of thread which is both interrupted and notified while waiting? I cannot understand how it is even possible because when we call
Thred.interrupt()
or
obj.notify()
the thread will be removed from the wait set. Since further call doesn't relate to a waiting thread. It has been removed from wait set yet.
Consider this code:
synchronized(obj) {
obj.notify();
threadWatingOnObj.interrupt();
}
Before the thread executing the above code releases the lock, no notified thread will be able to proceed. Therefore, when control returns to such a thread from its obj.wait() call, it will have been both notified and interrupted.
That looks like a question from an exam. You're supposed to fill in the blank, right?
I think the question is poorly thought out because "interrupted" is a state that a thread can be in, and "waiting" is a state that a thread can be in, but "notified" is not a state.
If a thread calls wait() when it is already in the interrupted state, then the wait() call will return an exception. Likewise, if a thread is in the waiting state when it becomes interrupted, then the wait() call will return an exception in that case too.
Maybe when they say "a thread is both notified and interrupted", they mean that the thread was waiting, and it was notified, and then an interrupt was delivered while the thread still was in the wait() call, trying to re-acquire the mutex.
I have no inside knowledge of what happens in that case, but based on the Javadoc for Object.wait(), I would expect the wait() call to return normally after it acquires the mutex.
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.
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.