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.