为什么不在 ForkJoinPool 中使用虚拟线程?

作者: zhl 分类: JavaSE,JUC 发布时间: 2025-01-20 10:17

刚才看到一张帖子提到为什么在 ForkJoinPool 中不使用虚拟线程?
在 JDK 21 中进行测试

public static void main(String[] args) throws InterruptedException {
    Runnable task = () -> {
        System.out.println("Running : " + Thread.currentThread());
    };
    /* 虚拟线程默认没有名字*/
    Thread thread = Thread.ofVirtual().name("VT").start(task);
    ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
    forkJoinPool.execute(task);
    Thread.sleep(1000);
}

发现 ForkJoinPool 的任务是在平台线程 (platform thread) 中执行的,但是虚拟线程中的任务是在 ForkJoinPool 中实现的,难道虚拟线程可以替代池化吗?
平台线程由操作系统调度,创建和销毁慢,资源消耗较高,每次线程的上下文切换涉及到内核态线程的上下文切换。而虚拟线程是基于平台线程实现的,可创建数百万线程,由 JVM 调度,创建和销毁快,资源消耗较低,不涉及操作系统层面的上下文切换。

ForkJoinPool 常用来做并行计算,及并行流parallel stream的底层实现。

为什么不在 ForkJoinPool 中使用虚拟线程?

  1. ForkJoinPool 适用于 CPU 密集型任务,虚拟线程适用于 IO 密集型任务
  2. CPU 密集型任务不需要大量超过 CPU 个数的线程,这对于大量的计算并没有很大的提升
  3. 虚拟线程创建和销毁较廉价,且资源消耗低,一般任务执行完就销毁,没必要池化 (pool)

参考资料:
https://www.reddit.com/r/java/comments/1i3owiv/why_are_virtualthreads_not_used_in_the_common/
https://berksoftware.com/24/1/When-Not-To-Use-Virtual-Threads
https://openjdk.org/jeps/425
https://popcornylu.gitbooks.io/java_multithread/content/threadpool/forkjoin.html

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注