10

我想创建一个固定大小的线程池,它不允许任何任务进入其队列。换句话说,如果线程池当前正在使用,那么传入的任务应该被彻底拒绝。根据文档,在我看来,一种方法是创建一个拒绝承认任务的虚拟 Queue 对象。在 Java 中实现此目的的惯用方法是什么?

4

3 回答 3

16

您可以在 ThreadPoolExector 中使用SynchronousQueue,它是一个不包含任何对象的队列。缓存线程池使用它是因为它按需创建新线程。

如果它不能排队,但我建议使用RejectedExecutionHandler在当前线程中运行任务。这样,它将始终“立即”运行。

顺便说一句:明确你为什么要这样做会很有用。

于 2012-04-17T07:17:02.887 回答
2

我想创建一个固定大小的线程池,它不允许任何任务进入其队列。

对于后代,如果您需要一个没有队列并且运行所有作业的线程池(与 OP 略有不同),那么您可以使用SynchronousQueuewhich 将阻塞,直到线程准备好执行该作业。诀窍是在将阻塞的队列上使用RejectedExecutionHandlerwhich 调用put(...)

threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
  unit, new SynchronousQueue<Runnable>(),
  new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor){
      try {
        // this needs to be put(...) and not add(...)
        executor.getQueue().put(runnable);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
  });

您将能够提交作业,直到maximumPoolSize达到线程数,然后提交将阻塞,直到作业完成并且线程可用于从SynchronousQueue.

于 2019-08-30T14:08:16.587 回答
0

你能详细说明你为什么要做这样的事情吗?TP + Q 的根本目的是为工作建立一个自动“持有机制”,并将工人与工作创建过程分离。如果您的意图是只拥有与工人一样多的可接受的工作包,那么您真的不需要 TPE。

于 2012-04-17T06:49:20.287 回答