When Does Java's Thread.Sleep Throw Interruptedexception

When does Java's Thread.sleep throw InterruptedException?

You should generally NOT ignore the exception. Take a look at the following paper:

Don't swallow interrupts

Sometimes throwing InterruptedException is
not an option, such as when a task defined by Runnable calls an
interruptible method. In this case, you can't rethrow
InterruptedException, but you also do not want to do nothing. When a
blocking method detects interruption and throws InterruptedException,
it clears the interrupted status. If you catch InterruptedException
but cannot rethrow it, you should preserve evidence that the
interruption occurred so that code higher up on the call stack can
learn of the interruption and respond to it if it wants to. This task
is accomplished by calling interrupt() to "reinterrupt" the current
thread, as shown in Listing 3. At the very least, whenever you catch
InterruptedException and don't rethrow it, reinterrupt the current
thread before returning.

public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;

public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}

public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
}
  • From Don't swallow interrupts

See the entire paper here:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

Java Thread Sleep and Interrupted Exception

  1. Because a Thread cant complete its normal execution if you Interrupt it, and you need to catch that in order to be prepared to do something.
  2. Because a thread waiting is different from an interrupted thread, a thread waiting can be resumed, but an interrupted thread is already finish execution.

When InterruptedException thrown from Thread.sleep?

As I know, InterruptedException is generated when you try to kill/interrupt the thread that is sleeping.

Does Thread.sleep throw if the thread was already interrupted?

Yes, it does.

The documentation perhaps isn't crystal clear on that point, but this is easy to both test (see the your own answer below, for example), and to see the canonical (HotSpot) implementation. Thread.sleep shells out to os:sleep which checks interruption before staring the sleep process as you can see here (look for os:sleep).

If this wasn't the case, interrupts would be more or less impossible to use. If they happened to arrive outside of any sleep() call they would be lost as subsequent sleep() calls would ignore them. You couldn't even re-interrupt the thread because it is already interrupted.

When to use thread.interrupt() and when to throws InterruptedException

See this other answer, which links to a very good discussion of interrupts. The main idea is that you should throw the InterruptedException, except where it is impossible. If it's impossible, you should reset the interrupted status by calling Thread.currentThread().interrupt().

Why might it be impossible to rethrow the interrupted exception? You might be calling Thread.sleep() inside the run() method of a class that implements Runnable (which it doesn't look like you are). Because InterruptedException is checked and the run method is not declared to throw any exceptions in the Runnable interface, you cannot rethrow the exception. In that case, it is best to reset the interrupted status, and many containers that use Runnable will handle that properly.

In any case, you're doing the right thing by changing the code so it doesn't swallow the exception.

How the main thread sleep/interrupt works in following code

Interruption is a polite request to stop: a Thread is under no obligation to stop.

It's like the Robin Williams joke about what police in the UK say when you commit a crime:

Stop! Or I'll say stop again!

Also, interrupting a thread doesn't cause an InterruptedException to be thrown: it merely sets a flag on the thread. If something (like Thread.sleep) checks this flag, and finds that it is set, it may then throw an InterruptedException; but the flag and exception are two orthogonal ways of indicating interruption.

As such:

  • On the first execution, you sleep for 3 seconds, then set the interrupted flag, and the loop body finishes normally.
  • On the second execution, you ask to sleep for 3 seconds, but Thread.sleep detects the interrupted flag, and throws the exception.

Thread Interrupt while sleeping

You are discarding the interrupt when you catch the InterruptedException. There is two solutions.

while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1500);

} catch (InterruptedException e) {
Thread.currentThread.interrupt();
}
}

or much simpler is to only catch the Exception outside the loop.

try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(1500);
}
} catch (InterruptedException e) {
Thread.currentThread.interrupt();
}

EDIT: I assume this is just an exercise as it would be far simpler to use an ExecutorService

public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newSingleThreadExecutor();

for (String message : "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".split(",")) {
System.out.println(getThreadName() + ": Sending " + message);
service.submit(() -> {
System.out.println(getThreadName() + ": Recevied " + message);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("--- Interrupted");
}
});
}
service.shutdown();
service.awaitTermination(1, TimeUnit.SECONDS);
service.shutdownNow();
}

public static String getThreadName() {
return Thread.currentThread().getName();
}

prints

main: Sending a
main: Sending b
main: Sending c
main: Sending d
main: Sending e
main: Sending f
main: Sending g
main: Sending h
main: Sending i
main: Sending j
main: Sending k
main: Sending l
main: Sending m
main: Sending n
main: Sending o
main: Sending p
main: Sending q
main: Sending r
main: Sending s
main: Sending t
main: Sending u
main: Sending v
main: Sending w
main: Sending x
main: Sending y
main: Sending z
pool-1-thread-1: Recevied a
pool-1-thread-1: Recevied b
--- Interrupted


Related Topics



Leave a reply



Submit