Java:ExecutorService 在特定队列大小后阻止提交

标签 java concurrency threadpool executorservice

我正在尝试编写一个解决方案,其中单个线程产生可以并行执行的 I/O 密集型任务。每个任务都有重要的内存数据。所以我希望能够限制当前待处理的任务数量。

如果我这样创建 ThreadPoolExecutor:

    ThreadPoolExecutor executor = new ThreadPoolExecutor(numWorkerThreads, numWorkerThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(maxQueue));

然后 executor.submit(callable) 在队列填满并且所有线程都已经忙时抛出 RejectedExecutionException

当队列已满且所有线程都忙时,我该怎么做才能使 executor.submit(callable) 阻塞?

编辑: 我试过this :

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

而且它在某种程度上达到了我想要达到的效果,但是以一种不优雅的方式(基本上被拒绝的线程在调用线程中运行,所以这会阻止调用线程提交更多)。

编辑:(提出问题 5 年后)

对于阅读此问题及其答案的任何人,请不要将已接受的答案视为一种正确的解决方案。请仔细阅读所有答案和评论。

最佳答案

我也做过同样的事情。诀窍是创建一个 BlockingQueue,其中 offer() 方法实际上是 put()。 (你可以使用任何你想要的基本 BlockingQueue 实现)。

public class LimitedQueue<E> extends LinkedBlockingQueue<E> 
{
    public LimitedQueue(int maxSize)
    {
        super(maxSize);
    }

    @Override
    public boolean offer(E e)
    {
        // turn offer() and add() into a blocking calls (unless interrupted)
        try {
            put(e);
            return true;
        } catch(InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
        return false;
    }

}

请注意,这仅适用于 corePoolSize==maxPoolSize 的线程池,因此请小心(请参阅注释)。

关于Java:ExecutorService 在特定队列大小后阻止提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4521983/

相关文章:

java - 接受通用列表作为参数并根据其类型使用它

ruby-on-rails - 如何捕获线程中的错误,然后在所有线程完成后重新抛出该错误?

c# - 为什么Task Parallel Library在某些情况下调度任务会出现 'hidden' 1秒超时?

.net - 通过 ThreadPool 循环时,我的 ThreadStatic 变量中的值是否仍然存在?

java - Tapestry 5 - 在 Java 代码中动态生成 W​​eb 应用程序上下文文件夹中文件的 URL

java - 如何在 Eclipse 中制作自定义编译器警告?

c++ - 如何从 dispatch_apply (GCD) 循环写入数组?

Python多线程并没有提高速度

c# - 使用线程池复制 100.000 个文件

java - 根据失败 Actor 的策略决策