I was reading thread interrupting from this article. It says following:
Before a blocking code throws an
InterruptedException
, it marks the interruption status as false. Thus, when handling of theInterruptedException
is done, you should also preserve the interruption status bycallingThread.currentThread().interrupt()
.Let’s see how this information applies to the example below. In the task that is submitted to the
ExecutorService
, theprintNumbers()
method is called twice. When the task is interrupted by a calltoshutdownNow()
, the first call to the method finishes early and then the execution reaches the second call. The interruption is called by the main thread only once. The interruption is communicated to the second execution of theprintNumber()
method by the call toThread.currentThread().interrupt()
during the first execution. Hence the second execution also finishes early just after printing the first number. Not preserving the interruption status would have caused the second execution of the method to run fully for 9 seconds.public static void main(String[] args) throws InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<?> future = executor.submit(() -> { printNumbers(); // first call printNumbers(); // second call }); Thread.sleep(3_000); executor.shutdownNow(); // will interrupt the task executor.awaitTermination(3, TimeUnit.SECONDS); } private static void printNumbers() { for (int i = 0; i < 10; i++) { System.out.print(i); try { Thread.sleep(1_000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // preserve interruption status break; } } }
I tried running above code and it prints:
01230
When I comment Thread.currentThread().interrupt();
from catch
block, it prints:
01230123456789
Though I feel I understand explanation before code, I dont think I understand why the explanation is correct, partly because I did not find any related explanation / sentence in the official doc. Here are my specific doubts:
Does that mean we need every method call in
Runnable
submitted toExecutorService.submit()
to have catchInterruptedException
and callThread.currentThread().interrupt()
in it for wholeRunnable
body to interrpt? If we miss to catchInterruptedException
and callThread.currentThread().interrupt()
in any method call inRunnable
, then it will not be interrupted?If above is correct, why there is not such explanation in the doc of
Thread.interrupt()
?Is it like if we want to do any closure task on interruption in any method, then only we should catch
InterruptedException
, perform any task to be done and then callThread.currentThread().interrupt()
?If answer to question 3 is yes, then when we should be doing closure task? I feel any closure task should be done before
Thread.currentThread().interrupt()
, but in the given example,break
is called afterThread.currentThread().interrupt()
.After thinking on question 4 a bit more, I feel I dont understand it clearly how thread interruption is handled. Earlier I felt interrupted thread simply gets killed immediately, but that does not seem to be the case. How thread interruption occurs? Is there any oracle official link explaining the same?