2

我想为 a 使用有界队列,ThreadPoolExecutor但我想使用我的自定义RejectedExecutionExceptionHandler。我需要这样做,以便我可以将被拒绝的任务放入单独的队列中,并在一段时间后尝试重新提交它们。
定制RejectedExecutionExceptionHandler是我的问题的解决方案吗?如果是,我该如何实施?
否则,处理我的问题的最佳方法是什么?

4

2 回答 2

2

在您的情况下,您可能希望选择仅在有界队列被填满时才会播放的饱和策略。可以通过调用setRejectedExecutionHandler()方法来修改线程池执行器的饱和策略。饱和策略有四种类型:

  1. 中止(这实际上会引发异常并让调用者处理它)
  2. Discard(这实际上是丢弃了新提交的任务)
  3. 丢弃 - 最旧的(这会丢弃接下来要运行的任务并尝试重新提交新任务)
  4. 调用者运行策略实现某种形式的限制,既不丢弃任务也不抛出异常,而是尝试通过将一些工作推回调用者来减慢新任务的流动。因此,调用者线程忙于运行新任务,因此在此期间无法接受任何更多任务。

对于您的情况,我认为CallerRunsPolicy()最有意义。做这个 :

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
于 2012-08-07T09:05:59.667 回答
1

我会使用无界队列,因为这会将无法运行的任务排队以供以后使用。在你的情况下,我会起诉 Executors.newFixedThreadPool。您可能对它的作用感兴趣

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

注意:它使用无界队列。

恕我直言,处理该问题的最简单/最好的方法是在当前线程中运行任务。

这可确保使用没有备用后台线程的当前线程及时执行所有任务。

new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        r.run();
    }
}
于 2012-08-06T08:59:21.930 回答