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