无法使用 SingleThreadExecutor 取消正在运行的任务
我有实现 Runnable 的类:
public class Abc implements Runnable{
public synchronized void run(){
while(!(Thread.currentThread().isInterrupted() || someCondition())){
doSomething();
try{
this.wait(SOME_TIME);
} catch(InterruptedException ex){
logger.error("Ex",ex);
Thread.currentThread.interrupt();
}
}}}
将其提交到线程池后,我想通过中断取消它。
futureTask.cancel(true);
但今天我的 Runnable 对象停止接收中断。 我已注销中断状态: false。不会抛出 InterruptedException。有什么建议吗?有什么问题吗?
I have class implementing Runnable:
public class Abc implements Runnable{
public synchronized void run(){
while(!(Thread.currentThread().isInterrupted() || someCondition())){
doSomething();
try{
this.wait(SOME_TIME);
} catch(InterruptedException ex){
logger.error("Ex",ex);
Thread.currentThread.interrupt();
}
}}}
After submiting it to threadpool I would like to cancel it, with interrupt.
futureTask.cancel(true);
But today my Runnable
object stopped receiving interrupt.
I've logged out interrupt state : false. InterruptedException
is not thrown. Any suggestions what is wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我的猜测是,中断被 doSomething 消耗,或者 doSomething 被占用(不返回)
在这样的循环中使用 wait() 对我来说,这表明您有一个更适合使用并发库的控制流。您能否提供更多有关您在等待什么的详细信息?
顺便说一句,如果将 try/cath 移到循环之外,它会简化它。
My guess is that the interrupt was consumed by doSomething or doSomething was tied up (not returning)
Using wait() in a loop like this suggest to me that you have a control flow which would be better suited to using the Concurrency libraries. Can you give some more details as to what you are waiting for?
BTW, If you move the try/cath to outside the loop it would simplify it.
首先,您的代码片段甚至无法编译:您缺少大括号,Thread.currentThread 是方法而不是实例变量。那么,您是否在 doSomething 方法中调用 Thread.interrupted() ?如果是:清除线程的中断状态,这样wait就不会被中断,currentThread().isInterrupted()将返回false。
您也不需要在 while 子句中重新检查中断状态或在线程被中断后重新中断线程。这看起来更好(并且捕获您的 doSomething 可能抛出的异常):
@Peter:移动 try/catch while 绝对是一个很好的建议!
First you snippet doesn't even compile: you are lacking braces, Thread.currentThread is a method not an instance variable. Then, are you calling Thread.interrupted() in your doSomething method? If yes: it clears the interrupted state of a thread, so that wait won't be interrupted and currentThread().isInterrupted() will return false.
You also don't need to recheck interrupted state in the while clause or reinterrupt the thread once it got iterrupted. This looks nicer (and catches exception that your doSomething might throw):
@Peter: moving try/catch around while is definitely a good suggestion!
已解决
这实际上是非常棘手的竞争条件。我一直从 gui 线程启动任务并从网络阅读器线程取消它。我无法解释为什么 log4j 不显示记录器,但更好的线程控制解决了我的问题。您的回答帮助我找到了解决该问题的想法,谢谢。
当某些东西昨天起作用但今天不起作用时 - 可能是它的竞争条件或死锁。 :-)
Solved
This was actually very tricky race condition. I've been starting task from gui thread and cancelling it from network reader thread. I cannot explain why log4j didn't display loggers but better thread control resolved my issue. Your answers helped me to track an idea to solve it, thanks.
When something worked yesterday but not today - probably its race condition or deadlock. :-)