English 中文(简体)
Interrupting a thread that waits on a blocking action?
原标题:

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();
  }
最佳回答

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();
}
问题回答

Only a few, well-defined "blocking methods" are interruptible. If a thread is interrupted, a flag is set, but nothing else will happen until the thread reaches one of these well-defined interruption points.

For example, read() and write() calls are interruptible if they are invoked on streams created with a InterruptibleChannel. If a Socket is used as the starting point, calling interrupt() on a Thread blocked in the read has no effect. Note that if a blocking I/O operation is interrupted successfully, the underlying channel is closed.

Another large class of interruptible operations are those thrown by various blocking operations on classes in the java.util.concurrent packages. Of course, the original wait() method is interruptible as well.

Blocking methods can be identified by looking for a throws InterruptedException in their method signatures. They should be well-documented too, to describe any side-effects of interruption.

You can write an interruptible method of your own, but it has to be composed of interruptible lower-level operations itself.

ok, people, don t kill me over this.

I experimented with Thread.stop() for fun, to kick thread out of a blocking action, catch ThreadDeath, keep target thread alive, and move on.

It seems working. The world isn t ending. But I m just saying. You are responsible for you own doing. Why am I rapping?

You stop method is calling interrupt on the wrong thread. Thread.currentThread() is the thread that is interrupting, not being interrupted.

How are you calling stop from the executing thread?
If you call stop() from another thread, you ll kill it, not the thread running in the try/catch block.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签