中断等待阻塞操作的线程?

时间:2009-11-30 14:22:40

标签: java multithreading interrupt-handling

我正在运行一个线程,其主要操作是使用阻塞函数调用代理,并等待它给它一些东西。

我使用了挥发性布尔值和中断的已知模式,但我不确定它是否会起作用:当我尝试为InterruptedException添加一个catch块时,我收到错误:

  

InterruptedException的无法访问的catch块。永远不会从try语句主体

抛出此异常

因此,如果我永远不会得到InterruptedException,这意味着我永远不会退出阻挡行动 - 因此永远不会停止。

我有点不解。有什么想法吗?

  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();
  }

5 个答案:

答案 0 :(得分:12)

首先,你真的不需要一个单独的标志(如果你这样做,使用AtomicBoolean),只需检查Thread.currentThread().isInterrupted()作为你的条件。

其次,你的stop方法不起作用,因为它不会中断正确的线程。如果另一个线程调用stop,则代码使用Thread.currentThread(),这意味着调用线程将被中断,而不是正在运行的线程。

最后,什么是阻止方法?是scheduleSource()吗?如果该方法没有抛出InterruptedException,您将无法捕获它。

尝试以下方法:

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();
}

答案 1 :(得分:11)

只有少数明确定义的“阻止方法”是可以中断的。如果线程被中断,则设置一个标志,但在线程到达这些明确定义的中断点之一之前不会发生任何其他事情。

例如,read()write()调用在使用InterruptibleChannel创建的流上调用时是可中断的。如果使用Socket作为起点,则在读取中被阻止的interrupt()上调用Thread无效。请注意,如果成功中断阻塞I / O操作,则会关闭基础通道。

另一大类可中断操作是由java.util.concurrent包中的类的各种阻塞操作引发的操作。当然,原始的wait()方法也是可以中断的。

可以通过在方法签名中查找throws InterruptedException来识别阻止方法。它们也应该被充分记录,以描述中断的任何副作用。

您可以编写自己的可中断方法,但它必须由可中断的低级操作本身组成。

答案 2 :(得分:2)

stop方法在错误的线程上调用interruptThread.currentThread()是正在中断的线程,而不是被中断。

答案 3 :(得分:2)

好吧,伙计们,不要因此而杀了我。

我尝试使用Thread.stop()获取乐趣,将线程从阻塞操作中解脱出来,捕获ThreadDeath,保持目标线程活着,然后继续。

看起来很有效。世界并没有结束。但我只是说。你对自己的行为负责。我为什么要说唱?

答案 4 :(得分:1)

你如何从执行线程中调用停止?
如果你从另一个线程调用stop(),你将杀死它,而不是在try / catch块中运行的线程。