6

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

我使用了 volatile boolean 和 Interruption 的已知模式,但我不确定它是否会起作用:当我尝试为 添加 catch 块时InterruptedException,出现错误:

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

5 回答 5

12

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

例如,read()如果write()在使用InterruptibleChannel. 如果以 aSocket为起点,则在 read 中调用interrupt()阻塞Thread是没有效果的。请注意,如果阻塞 I/O 操作成功中断,则底层通道将关闭。

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

throws InterruptedException可以通过在方法签名中查找 a 来识别阻塞方法。它们也应该有据可查,以描述中断的任何副作用。

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

于 2009-11-30T15:20:48.997 回答
12

首先,您实际上并不需要单独的标志(如果需要,请使用AtomicBoolean),只需检查Thread.currentThread().isInterrupted()您的 while 条件即可。

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

最后,阻塞方法是什么?是scheduleSource()吗?如果该方法不 throw 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();
}
于 2009-11-30T14:38:05.510 回答
3

好吧,人们,不要因此杀了我。

为了好玩,我尝试了 Thread.stop(),将线程从阻塞操作中踢出,捕获 ThreadDeath,保持目标线程处于活动状态,然后继续前进。

它似乎工作。世界没有终结。但我只是说。你要为你自己的所作所为负责。我为什么要说唱?

于 2009-11-30T20:35:40.310 回答
2

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

于 2009-11-30T14:38:39.300 回答
1

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

于 2009-11-30T14:36:31.237 回答