相关疑难解决方法(0)

Java:在某个队列大小之后阻止提交的ExecutorService

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

如果我像这样创建ThreadPoolExecutor:

    ThreadPoolExecutor executor = new ThreadPoolExecutor(numWorkerThreads, numWorkerThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(maxQueue));
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:我试过这个:

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
Run Code Online (Sandbox Code Playgroud)

它有点实现了我想要实现的效果但是以一种不雅的方式(基本上被拒绝的线程在调用线程中运行,因此这阻止了调用线程提交更多).

编辑:(提问后5年)

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

java concurrency executorservice threadpool

73
推荐指数
5
解决办法
4万
查看次数

优雅地将队列长度指示符实现到ExecutorServices

为什么,为什么不java.util.concurrent提供其ExecutorServices 的队列长度指标?最近我发现自己做了这样的事情:

ExecutorService queue = Executors.newSingleThreadExecutor();
AtomicInteger queueLength = new AtomicInteger();
...

public void addTaskToQueue(Runnable runnable) {
    if (queueLength.get() < MAX_QUEUE_LENGTH) {
        queueLength.incrementAndGet(); // Increment queue when submitting task.
        queue.submit(new Runnable() {
            public void run() {
                runnable.run();
                queueLength.decrementAndGet(); // Decrement queue when task done.
            }
        });
    } else {
        // Trigger error: too long queue
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个工作正常,但......我认为这应该作为一部分实现ExecutorService.这是一个愚蠢的错误,容易携带一个与实际队列分开的计数器,计数器应该指示它的长度(让我想起C数组).但是,ExecutorServices是通过静态工厂方法获得的,因此无法简单地扩展优秀的单线程执行器并添加队列计数器.所以我该怎么做:

  1. 重新发明已经在JDK中实现的东西?
  2. 其他聪明的解决方案?

java queue concurrency executorservice executor

33
推荐指数
1
解决办法
2万
查看次数