Java - Thread problem
My question is related to all those methods(including Thread.sleep(...)
) which throw InterruptedException
.
I found a statement on Sun's tutorial saying
InterruptedException
is an exception thatsleep
throws when another thread interrupts the current thread while sleep is active.
Is that means that the interrupt will be ignored if the sleep
is not active at the time of interrupt?
Suppose I have two threads: threadOne
and threadTwo
. threadOne
creates and starts threadTwo
. threadTwo
executes a runnable whose run method is something like:
public void run() {
:
:
try {
Thread.sleep(10 * 1000);
} catch (In开发者_JS百科terruptedException e) {
return;
}
:
:
: // In the middle of two sleep invocations
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
}
After thread creation, threadOne
interrupts threadTwo
. Suppose the threadTwo
is in the middle of two sleep invocations at the time of interrupt (when no sleep method was active), then will the second sleep method throw InterrupteException
as soon as it is invoked?
If not, then will this interrupt will be ignored forever?
How to be sure that threadTwo
will always know about the interrupt (doesn't matter whether its one of the sleep method is active or not)?
From javadoc:
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.
This means that you have to check the interrupted status to be sure your thread knows about the interruption. This can be done with two methods: isInterrupted() and interrupted(). The last one clear the interrupted status.
Something like this:
while(!Thread.interrupted()) {
...
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
}
On Sun's Windows JDK, the thread will in fact throw InterruptedException
when entering sleep()
:
public static final void main(String args[]) throws Exception {
final Thread main = Thread.currentThread();
Thread t = new Thread() {
@Override
public void run() {
main.interrupt();
}
};
t.start();
t.join();
Thread.sleep(1000);
System.out.println("Not interrupted!");
}
The API documentation of sleep()
can be interpreted to mean that this is mandatory behaviour:
throws InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
But that's not very clear, so I wouldn't depend on it and instead check isInterrupted()
manually.
The Java documentation is a tad misleading. If the interrupted status of a thread is set, calling sleep()
on that thread will cause an InterruptException
to be thrown immediately.
This applies even if the thread was interrupted before sleep()
was called.
As stated above, though, you can also check with Thread.isInterrupted()
if you want to handle interrupts yourself.
The InterruptionException is only of interest during the sleep of the thread. It won't be thrown by the later sleep() call if the thread has been interupted anywhere before. Only the interuption at the time of the sleep() does matter because it breaks exactly that sleep() call.
精彩评论