无法使用 SingleThreadExecutor 取消正在运行的任务

发布于 2024-11-03 11:52:52 字数 597 浏览 4 评论 0原文

我有实现 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月静好 2024-11-10 11:52:52

我的猜测是,中断被 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.

岁月染过的梦 2024-11-10 11:52:52

首先,您的代码片段甚至无法编译:您缺少大括号,Thread.currentThread 是方法而不是实例变量。那么,您是否在 doSomething 方法中调用 Thread.interrupted() ?如果是:清除线程的中断状态,这样wait就不会被中断,currentThread().isInterrupted()将返回false。

您也不需要在 while 子句中重新检查中断状态或在线程被中断后重新中断线程。这看起来更好(并且捕获您的 doSomething 可能抛出的异常):

  public synchronized void run() {
    try {
      while (!someCondition()) {
        doSomething();
        wait(SOME_TIME);
      }
    } catch (InterruptedException ie) {
      logger.error(ie);
    } catch (Exception e) {
      logger.error(e);
    }
  }

@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):

  public synchronized void run() {
    try {
      while (!someCondition()) {
        doSomething();
        wait(SOME_TIME);
      }
    } catch (InterruptedException ie) {
      logger.error(ie);
    } catch (Exception e) {
      logger.error(e);
    }
  }

@Peter: moving try/catch around while is definitely a good suggestion!

救赎№ 2024-11-10 11:52:52

已解决

这实际上是非常棘手的竞争条件。我一直从 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. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文