views:

216

answers:

4

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 that sleep 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 (InterruptedException 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)?

+4  A: 

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;
  }
}
Andrea Polci
Nice, I just learned something new. I was wondering how to get the interrupt status.
Tom Dignan
@Andrea Why u used `isInterrupted()` and not `interrupted()`? I think that the interrupt status should be cleared when the thread knows that it has been interrupted.
Yatendra Goel
@Yatendra Goel You are right, changed the example.
Andrea Polci
@Andrea Change `Thread.currentThread().interrupted()` to `Thread.interrupted()` as it is a static method.
Yatendra Goel
@Yatendra Goel done, sorry!
Andrea Polci
A: 

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.

Daniel Bleisteiner
Why `InterruptedException` is only of interest during the sleep method? I am interested in that exception even when the thread is not sleeping because I want to stop that thread when being interrupted.
Yatendra Goel
That's actually not true, at least on Sun's Windows JDK.
Michael Borgwardt
Then I'm a victim of the not so clear documentation... sorry for my early response.
Daniel Bleisteiner
+2  A: 

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.

Michael Borgwardt
@Michael What would u say on the answer of @zerocrates. Is the `sleep()` method always throw an `InterruptedException` if an the thread has been interrupted (whether the thread's sleep method was active or not)?........ Are you trying to say that this behavious of sleep method is not clear?...... If this is true, then I will have to provide the code, that is executed after the thread has been interrupted, at two places: one in the `catch` clause of sleep method and other in the if block `if (Thread.interrupted()) because if the sleep method throws exception then it will clear the interrupt ...
Yatendra Goel
... status and the subsequent `if (Thread.interrupted())` block will return false.
Yatendra Goel
@Yatandra: as I wrote: since the behaviour is not clearly stated in the API doc, I would not depend on it. Put the code that should be executed upon interruption into a separate method and call it from both places.
Michael Borgwardt
+2  A: 

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.

zerocrates