Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 中断等待阻塞操作的线程?_Java_Multithreading_Interrupt Handling - Fatal编程技术网

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

Java 中断等待阻塞操作的线程?,java,multithreading,interrupt-handling,Java,Multithreading,Interrupt Handling,我正在运行一个线程,其主要操作是使用阻塞函数调用代理,并等待它给它一些东西 我使用了已知的volatile boolean模式和中断模式,但我不确定它是否有效:当我尝试为InterruptedException添加catch块时,我得到了错误: InterruptedException的不可访问捕获块。决不会从try语句体引发此异常 因此,如果我永远都不会得到一个中断异常,这意味着我永远都不会摆脱阻塞操作,因此永远不会停止 我有点困惑。有什么想法吗 public void run() {

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

我使用了已知的volatile boolean模式和中断模式,但我不确定它是否有效:当我尝试为
InterruptedException
添加catch块时,我得到了错误:

InterruptedException的不可访问捕获块。决不会从try语句体引发此异常

因此,如果我永远都不会得到一个
中断异常
,这意味着我永远都不会摆脱阻塞操作,因此永远不会停止

我有点困惑。有什么想法吗

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

如何从执行线程调用stop?

如果从另一个线程调用stop(),您将杀死它,而不是try/catch块中运行的线程。

首先,您实际上不需要单独的标志(如果需要,请使用),只需将
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();
}
private final AtomicReference currentThread=new AtomicReference();
公开募捐{
Proxy Proxy=ProxyFactory.generateProxy();
来源;
currentThread.set(Thread.currentThread());
而(!Thread.currentThread().isInterrupted()){
试一试{
source=proxy.getPendingSources();
调度源(source);
}捕获(例外e){
log.error(“运行时捕获意外异常”,e);
}
}
}
公共停车场(){
currentThread.get().interrupt();
}

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

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

例如,
read()。如果使用
套接字
作为起点,则在读取中阻塞的
线程上调用
中断()
,没有任何效果。请注意,如果阻塞I/O操作成功中断,则底层通道将关闭

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

阻塞方法可以通过在其方法签名中查找
抛出InterruptedException
来识别。它们也应该有很好的文档记录,以描述中断的任何副作用


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

好了,各位,别因此杀了我

为了好玩,我尝试了Thread.stop(),将线程从阻塞操作中踢出,捕捉ThreadDeath,让目标线程保持活力,然后继续前进


它似乎起作用了。世界还没有结束。但我只是说。你对自己的行为负责。我为什么要说唱

谢谢!我花了几分钟的时间,但我已经意识到我在“停止”这个词上做错了什么。在这种情况下,如果线程将收到一个“停止”请求,它将停止等待阻止操作?或者最好使用一个易失性布尔值来标记停止。@Tom如果scheduleSource()或proxy.getPendingSources()被阻止怎么办?我假设他希望调用被stop()@yossale中断,如果线程在interruptple操作上被阻塞,调用stop()将中断它。当然,在编写可中断方法时,可以定期测试
thread#interrupted())
和throw
InterruptedException
在其他长时间运行的方法中,尤其是涉及循环的方法中,如果在该循环中调用的方法本身都不可中断,则每隔一段时间测试一次中断是有用的。