1

Why second example is better than the first one? Can someone explain me?

//1

public void run()
{
    while (. . .)
    {
        . . .
        try 
        { 
            . . .
            Thread.sleep(delay); 
            . . .
        } catch (InterruptedException exception) {}  
            . . .
        }
    }
}

//2

public void run() {
    try {
        while (. . .) {
         . . .
         Thread.sleep(delay);
         . . .
        }
    } catch (InterruptedException exception) {
        . . .
    } 
}

I heard that the first example, when InterruptedException occurs it does not terminate the thread, but I still do not understand why.

Queeg
  • 7,748
  • 1
  • 16
  • 42
wydra__
  • 25
  • 4
  • 2
    Catching the `InterruptedException` clears the interrupted flag of the thread. Generally the correct way to proceed is (1) set the interrupted flag again: `Thread.currentThread().interrupt();` (2) stop doing what you were currently doing since someone wanted to interrupt it; for example, return from the method (after doing any necessary clean-up). – Ole V.V. May 03 '23 at 12:13
  • 1
    See [The Secrets of Concurrency (Part 1)](https://www.javaspecialists.eu/archive/Issue146-The-Secrets-of-Concurrency-Part-1.html), the section *Law 1: The Law of the Sabotaged Doorbell*. – Ole V.V. May 03 '23 at 12:16
  • That said, in situations where the `InterrruptedException` surely cannot occur, I tend to do just `throw new AssertionError("This can’t happen", exception);` from the `catch` block. Never leave the the catch block without effect. – Ole V.V. May 03 '23 at 18:54
  • Closely related: [Handling InterruptedException in Java](https://stackoverflow.com/questions/3976344/handling-interruptedexception-in-java). It may even answer your question? – Ole V.V. May 03 '23 at 18:59

1 Answers1

4

Neither is better - it depends on what you intend to do.

The second example would break the while loop upon InterruptedException, the first example will just break one iteration and the thread would continue on the next.

The reason is that an InterruptedException, when thrown inside Thread.sleep() will break all execution until a catch block applies (or, if none such block is found, the thread terminates). In the second example this catch is outside the loop, therefore after having executed the catch the loop is gone.

But consider why your thread was interrupted in first place. As Ole put it: Stop doing what you were doing. If need be perform some cleanup work, then exit.

This may mean you have to exit the loop. It may mean you have to stay in the loop, or run some 'undo' loop. But in any case you have to deal with the fact that this thread actually needs to terminate. And since throwing an InterruptedException clears the interrupted flag of the thread, generally it is wise to set the interrupted flag again using Thread.currentThread().interrupt().

If your application needs to perform cleanup also see Runtime.addShutdownHook(), as similar concepts will apply to an interrupted thread:

Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit. When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.

Queeg
  • 7,748
  • 1
  • 16
  • 42
  • 1
    To comment further - one needs to consider **why** execution is interrupted. Threads don't just up and interrupt themselves. If, for example, the program is terminating, thus getting rid of its executing threads, the first could be a bug plain and simple, if it means the run-loop does not terminate. – Arfur Narf May 03 '23 at 11:40
  • We may not agree. If neither is better, then leaving the `catch` block empty is definitely worse IMHO. Excluding yourself from being informed about unexpected errors in your program is like coding blindfolded. – Ole V.V. May 03 '23 at 18:56
  • I believe the question was about where to place the catch block, not about leaving it empty. I agree leaving catch empty is a no-go. – Queeg May 04 '23 at 11:49