Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ThreadPoolExecutor和RejectedExecutionExceptionHandler_Java_Multithreading_Concurrency_Threadpool_Java.util.concurrent - Fatal编程技术网

Java ThreadPoolExecutor和RejectedExecutionExceptionHandler

Java ThreadPoolExecutor和RejectedExecutionExceptionHandler,java,multithreading,concurrency,threadpool,java.util.concurrent,Java,Multithreading,Concurrency,Threadpool,Java.util.concurrent,我想为ThreadPoolExecutor使用有界队列,但我想使用自定义RejectedExecutionExceptionHandler。我需要这样做,以便将被拒绝的任务放到单独的队列中,并在一段时间后尝试重新提交它们。 自定义RejectedExecutionExceptionHandler是我问题的解决方案吗?如果是,我如何实现一个? 否则,处理我的问题的最佳方式是什么 我会使用一个无界队列,因为这将对无法运行供以后使用的任务进行排队。在你的情况下,我会起诉Executors.newFix

我想为
ThreadPoolExecutor
使用有界队列,但我想使用自定义
RejectedExecutionExceptionHandler
。我需要这样做,以便将被拒绝的任务放到单独的队列中,并在一段时间后尝试重新提交它们。
自定义
RejectedExecutionExceptionHandler
是我问题的解决方案吗?如果是,我如何实现一个?

否则,处理我的问题的最佳方式是什么

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

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

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

  • 中止(这实际上会抛出一个异常并让调用方处理)
  • 放弃(这实际上会放弃新提交的任务)
  • Discard-Olested(这将丢弃下一个要运行的任务,并尝试重新提交新任务)
  • 调用者运行策略,该策略实现某种形式的限制,既不丢弃任务也不引发异常,而是尝试通过将部分工作推回到调用者来减慢新任务的流程。因此,调用线程忙于运行新任务,因此在此期间无法接受更多任务
  • 对于您的情况,我认为
    callerRunPolicy()
    最有意义。这样做:

    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    

    如果池关闭,这将忽略任务,但您可以使用它。这似乎合理,但我认为它会降低我的服务器的速度。为什么不使用单独的队列?请稍等片刻,然后重新提交它们?在任何情况下,只有当服务器过载时才会发生这种情况(假设池中有最佳数量的线程)默认情况下使用LinkedBlockingQueue。当前,如果可以,池将立即执行任何任务;如果线程没有空闲,则将其添加到队列中,以便稍后执行。您的建议与此有何不同?因此,您将有两个队列,共有N个任务,而不是一个队列,共有N个任务,但这两个队列在添加后很长时间内将有一些任务完成。与其问你为什么不应该这样做,你应该问;你为什么要让它变得更复杂?是什么让你不愿意使用无界队列呢?@DuncanJones:为了确保我不会让服务器过载,你不会让服务器过载,因为你仍然需要定义最大线程数。我将停止在这里发帖,因为你在彼得的回答中与他进行了同样的讨论。
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());