java - 当 ThreadPoolExecutor 提供任务时,SynchronousQueue 不会阻塞

标签 java multithreading concurrency

我使用了几乎默认的 newCachedThreadPool,但我想限制线程创建,所以我像这样创建 ExecutorService

new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<>());

阅读 javadocs 后,我希望它的工作方式是,当我提交 Runnable 时,taskExecutor 在向 SynchronousQueue 提供新任务时会阻塞,直到有可用线程来执行它,然后发生切换。不幸的是,在达到线程池容量后并且所有线程都忙时,taskExecutor 会抛出 RejectedExecutionException。我知道我可以传递一个会阻塞的 RejectedExecutionHandler,但我很惊讶似乎我必须这样做。有人可以解释一下它是否真的按预期工作还是我做错了什么?

此代码重现了我的案例:

public static void main(String[] args) {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<>());

    while (true) {
        executor.submit(() -> System.out.println("bla"));
    }
}

最佳答案

这符合ThreadPoolExecutor API:

• 如果请求无法排队,则会创建一个新线程,除非这超出了 MaximumPoolSize,在这种情况下,该任务将被拒绝。

至于为什么 SynchronousQueue 不会阻塞 - 因为 ThreadPoolExecutor 使用 queue.offer() 而不是 put()

关于java - 当 ThreadPoolExecutor 提供任务时,SynchronousQueue 不会阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44541784/

相关文章:

linux - clock_nanosleep 不返回 -1/set errno EINTR - LINUX

multithreading - golang写文件阻塞了很多goroutine,为什么不创建很多线程?

java - 如何在 Spring Boot 中处理 RequestParam 中的花括号

java - RSA加密——寻找P和Q

java - 在 Windows 上使用 evosuite

c - 将多个值返回到C中的线程时出错

python - 在多线程上进行预测时出现 Keras 错误

concurrency - 如何在 Rust 中的多个线程之间共享结构的不可变引用?

Java volatile 引用与 AtomicReference

java - 在深层层次结构中查找元素 - 迭代与递归