【问题标题】:How to use ExecutorService to handle an aborted Runnable?如何使用 ExecutorService 处理中止的 Runnable?
【发布时间】:2012-11-28 10:16:50
【问题描述】:

我有一个Workerimplements Runnable 和一个run() 方法,它可能会在发生冲突时引发异常并提前返回。当它发生时,该线程需要放回队列中才能再次运行。

通过查看this 问题,看来我需要用Callable 重写。那是对的吗? Runnable 没有办法做到这一点?

【问题讨论】:

  • 我已经读过了。它列出了方法和类型,但没有给出任何示例或说明使用 Runnables 处理异常的任何内容。我将问题编辑为更清楚。
  • 你也可以看看this
  • 您是否担心抛出未捕获的运行时异常的Runnable 不会返回到池中?
  • 我的run() 方法的一部分涉及到这个:try{//thingThatThrowsException}catch (TransactionAbortException e){return;} 恐怕是的,如果它返回这里,Runnable 将无法完成它的工作。

标签: java multithreading exception-handling


【解决方案1】:

你可以让工作线程自己做。如果你有执行人的控制权。

class RequeableWorker implement Runnable{
  private final ExecutorService e;
  public RequeableWorker(ExecutorService e){this.e =e;}

  public void run(){
     try{
        //do work
     }catch(RuntimeException ex){
        e.submit(this);
        throw ex;
     }
  }
}

或者正如您的回答所暗示的那样,等待 Future 重新排队的线程。

public void workOrRequeue(){
    for(;;){
       Future<?> future = e.submit(someCallable());
       try{
          future.get();
          return;
       }catch(ExecutionException ex){
          //maybe log, ex.printStackTrace();
       }
    }
}

【讨论】:

  • ...你能做到吗?那可行?如果我在主线程中声明一个 ExecutorService,我可以将它作为参数传递给 worker,然后让 worker 重新提交到队列中?
  • 如果worker接受其他参数怎么办?当它重新提交到队列中时,它们是否也会包含在新的提交中?
  • @Aerovistae 一般来说,ExecutorService由工作队列和线程组成。如果您传递 ExecutorService 并提交给它,您只是将可运行对象放在 ES 工作队列中。就是简单的委托,你可以看到这里也完成了docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/…
  • 这带来了不同类型的问题。如果需要重新定义工作人员,您会担心让 ES 做太多工作来检索新数据。如果 ES 实际上无法获取这些新数据,则需要使用我列出的第二个示例。最后,如果 RequeableWorker 实际上可以获取新参数,那么您可以在 submiting 之前获取它们
【解决方案2】:

正如Future.get() 的文档所说:

抛出:

[...]

ExecutionException - 如果计算抛出异常

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2014-06-27
    • 2015-01-03
    • 2019-08-03
    • 1970-01-01
    相关资源
    最近更新 更多