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

Yos*_*ale 5 java multithreading interrupt-handling

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

我已经使用了挥发性布尔值和中断的已知模式,但我不确定它是否会起作用:当我尝试添加一个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();
  }
Run Code Online (Sandbox Code Playgroud)

Kev*_*vin 12

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

其次,你的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();
}
Run Code Online (Sandbox Code Playgroud)

  • @Tom但是,如果scheduleSource()或proxy.getPendingSources()被阻止怎么办?我假设他希望该调用被stop()中断 (2认同)

eri*_*son 11

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

例如,read()并且write()如果他们是在与创建的流调用的调用是中断的InterruptibleChannel.如果Socket使用为出发点,要求interrupt()Thread挡在读不起任何作用.请注意,如果阻塞I/O操作成功中断,则关闭基础通道.

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

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

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