Interrupting a thread that waits on a blocking action?

Yossale picture Yossale · Nov 30, 2009 · Viewed 10.9k times · Source

I am running a thread whose main action is to call on a proxy using a blocking function , and wait for it to give it something.

I've used the known pattern of a volatile boolean and the Interruption , but I'm not sure it will work: When I tried to add a catch block for InterruptedException , I get the error:

Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body

So if I'm never going to get anInterruptedException, this means I'll never get out of the blocking action - thus will never stop.

I'm a bit puzzled. Any idea?

  public void run() {    
    Proxy proxy = ProxyFactory.generateProxy();
    Source source;

    while (!isStopped) {
      try {
        source = proxy.getPendingSources();
        scheduleSource(source);
      } catch (Exception e) {
        log.error("UnExpected Exception caught while running",e);
      }
    }
  }

  public void stop() {
    this.isStopped = true;
    Thread.currentThread().interrupt();
  }

Answer

Kevin picture Kevin · Nov 30, 2009

First, you don't really need a separate flag (if you do, use an AtomicBoolean), just check Thread.currentThread().isInterrupted() as your while condition.

Second, your stop method won't work because it won't interrupt the correct thread. If another thread calls stop, the code uses Thread.currentThread() which means the calling thread will be interrupted, not the running one.

Finally, what is the blocking method? Is it scheduleSource()? If that method doesn't throw InterruptedException, you won't be able to catch it.

Try the following:

private final AtomicReference<Thread> currentThread = new AtomicReference<Thread>();

public void run() {
    Proxy proxy = ProxyFactory.generateProxy();
    Source source;

    currentThread.set(Thread.currentThread());

    while (!Thread.currentThread().isInterrupted()) {
        try {
            source = proxy.getPendingSources();
            scheduleSource(source);
        } catch (Exception e) {
            log.error("UnExpected Exception caught while running", e);
        }
    }
}

public void stop() {
    currentThread.get().interrupt();
}