java - 奇怪的 ForkJoinPool 行为

标签 java concurrency java-8 threadpool

Java8 流和并行流使用 ForkJoinPool.commonPool 这是一个通用池(理论上保留与机器上的 CPU 一样多的线程)用于短任务...

我正在使用一些 java8 功能,我注意到池只保留一个线程并不断地杀死和替换它......

enter image description here

如果我选择只查看 Activity 线程,池中将只有一个线程...

enter image description here

那么问题来了,为什么池一直代替线程呢?为什么不重用它?这是正常行为吗? (如果是,为什么?)

最佳答案

我不认为你的推论是正确的。该池有 X 个线程。假设它以 5 个线程开始。现在将有 5 个线程处于 IDLE 状态。如果你交给它工作,它会将 1 个线程置于 ACTIVE 状态,然后一旦工作完成,它就会回到 IDLE。如果pool是有Queue支持的,首先拉取的线程是Thread0,然后到pool的后面,pool使用其他4个线程,然后Thread0才会被再次使用。这是它在您的图表中显示的模式。 您只看到 1 个线程处于 Activity 状态的原因可能是您的工作时间太短,以至于线程在下一个线程开始之前完成并返回 IDLE。

编辑

来自code : 它创建一个 LIFO 队列,如果无法确定其他属性/内核数量,则使用 1 个线程。根据您启动应用程序的方式,它可能会导致一些意外行为,但无法确定,因为我不了解您的系统或应用程序。上面的答案只是解释线程池的工作方式,根据这个解释可以理解你在第一张图片中显示的模式。

关于java - 奇怪的 ForkJoinPool 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29237418/

相关文章:

java - xtext:除了Eclipse 编辑器外,如何使用语法?

java - 无法在不删除前一个元素的情况下在 Arraylist 中添加 HashMap

java - Spring Kafka 应用程序的应用程序负载测试期间未找到主题错误

java - 对 CountedCompleter 的文档和来源感到困惑

multithreading - 如何将 parMap 与一元函数一起使用?

java - 对于给定的 Date 对象,捕获其与 GMT 时区相关的值

java - 我应该如何在 Openjpa 实体中使用枚举?

java - 具有多个订阅者和事件的 RxJava 并发

java - thenAccept 和 thenApply 的区别

java - 在 Java 8 中,是否有 ByteStream 类?