12

This IBM developerWorks article states:

“The one time it is acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable […]”.

I always implemented Runnable for my threads by now. Giving a Runnable implementation like this:

public class View() implements Runnable {
    @Overload
    public void run(){
        Thread worker = new Thread(new Worker());
        worker.start();
        do{
            try{
                TimeUnit.SECONDS.sleep(3);
                updateView();
            }catch(InterruptedException e){
                worker.interrupt();
                // Thread.currentThread().interrupt();
                return;
            }
        }while(true);
    }

    protected void updateView(){
        // …
    }
}

Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement? Doesn’t return; perform a clean enaugh exit already? What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”. What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown? Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?

BTW, is it a better code design to extend Thread instead of implementing Runnable?

Gray
  • 115,027
  • 24
  • 293
  • 354
Matthias Ronge
  • 9,403
  • 7
  • 47
  • 63
  • See [Extend Thread vs Implement Runnable](http://stackoverflow.com/q/541487/823393) the general consensus is to implement `Runnable`. – OldCurmudgeon Nov 20 '13 at 11:13

4 Answers4

11

It resets the interrupt flag. This JavaSpecialists newsletter covers this confusing topic in more detail.

In my example, after I caught the InterruptedException, I used Thread.currentThread().interrupt() to immediately interrupted the thread again. Why is this necessary? When the exception is thrown, the interrupted flag is cleared, so if you have nested loops, you will cause trouble in the outer loops

So if you know that your code is not going to be used by another component, then you don't need to re-interrupt. However I really wouldn't make that minor optimisation. Who knows how your code is going to be used/reused in the future (even by copy/paste) and consequently I would reset the flag for every interrupt.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
3

Here is an example where return it is not enough:

public void doSomething1() {
  while (someCondition1()) {
    synchronized {
       try {
         this.wait();
       } catch (InterruptedException e) {
         return; // Should be Thread.currentThread().interrupt();
       }
    }
  }
}
public void doSomething2() {
  while (someCondition2()) {
    doSomething1();
  }
}

As the exception throw clears the interrupted state next time doSomething1() is executed the status is cleared and the thread does not terminates.

aalku
  • 2,860
  • 2
  • 23
  • 44
1

I prefer extending Thread because it gives you a better understanding of what the thread is doing, but it is not necessarily better code design.

As Brian stated ,it resets the interrupt flag but that doesn't say much. In your case it will do nothing and the View-Thread will keep on running.

When interrupting a Thread, the standard procedure is that the Thread should stop running. It won't do this automatically and you have to implement a way to stop it once it is interrupted.

Using the built-in functionality there are two options:

  • Have the main loop inside the try-block for the InterruptedException. This way, when it is interrupted you you will be thrown out of the loop and the method will exit.
  • The above can be bad if you have to save the state as it may corrupt the state. As an alternative, you can set the interrupted-flag (as said when it's thrown. re-interrupt it Interrupt the Thread

Either way, you have to check that the Thread is interrupted in your while-loop (with !Thread.currentThread().isInterrupted()-statement in the while-loop) or it may/will not exit. You're not fulfilling one of the first options and neither checking the flag, so your View-thread will keep on running after being interrupted.

ddmps
  • 4,350
  • 1
  • 19
  • 34
  • extending thread is [a bad practice](http://stackoverflow.com/questions/541487/implements-runnable-vs-extends-thread)... – assylias Nov 20 '13 at 11:19
  • 1
    @assylias Nothing there says it's a bad practice. Implementing Runnable may be preferred for some issues but as I said, for understanding how it works Thread is a good way to go. – ddmps Nov 20 '13 at 12:16
0

Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement?

As a point, I always do. We all copy-and-paste code and swallowing the interrupt is such a serious problem that I as a rule always do it, even if the thread is about to die.

Doesn’t return; perform a clean enough exit already?

If you are sure that it is the last return before the run() method completes and the thread exits, then yes, it not technically necessary. But see above. For posterity, return; doesn't do anything with the interrupt flag.

The question is whether your View class has been wrapped. Are you sure that when you return you are exiting the Thread. Maybe someone is delegating to it. AOP may be in place to do some sort of instrumentation.

What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”.

In general, it is important to not swallow the interrupt when your code is called by some sort of wrapping code (delegation, AOP, etc) which needs the interrupt flag. If you are swallowing it, the wrapper won't be able to use it. But in this case, there is no benefit.

What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown?

Nothing. Once the thread exits the interrupt state is worthless. And actually, it looks like the interrupt state isn't even persisted after the thread is dead.

Thread thread = new Thread(new Runnable() {
    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("caught");
        }
    }
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());

Prints:

true
caught
false

Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?

I can't. There is no code outside of the thread's run() method unless someone is wrapping your runnable in other code without your knowledge.

This may happen if you are using an ExecutorService but in that case the thread's interrupt status is specifically cleared with a wt.isInterrupted() before the job is run.

So again, the reason is to do is is because it's a good pattern and that's what's important in software engineering.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • A concrete example of where it is used that I just ran into is the shutDownNow logic for the ExecutorService. It is checking the interrupt state to cancel running tasks. If the Callable or Runnable is not setting the interrupt state the task will run to completion which may not be desired if you are trying to stop the thread pool right now in a graceful way. [so any task that fails to respond to interrupts may never terminate.](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow--) – Draukadin Jul 06 '17 at 01:53