虚拟线程让「一个任务一个线程」重新可行,但它到底改变了什么?这篇用 JDK 21 在 macOS 上量出线程数上限、耗时、内存和纯计算任务的差别(pinning 在下一篇)。
虚拟线程:isVirtual=true,isDaemon=true,名字=""(默认空),优先级=5 平台线程:isVirtual=false,isDaemon=false,名字="Thread-0" 虚拟线程里 Thread.currentThread() 的 toString = VirtualThread[#N]/runnable@ForkJoinPool-1-worker-K 2000 个虚拟线程(每个先 sleep 50 ms 再继续),一共在 10 个不同的载体线程上运行过(机器核数 10)
虚拟线程 10000 个任务各 sleep 1 秒:0.5 秒时 RSS 85 MB,总耗时 1073 ms,完成 10000 个 [1.309s][warning][os,thread] Failed to start thread "Unknown thread" - pthread_create failed (EAGAIN) for attributes: stacksize: 2048k, guardsize: 16k, detached. [1.309s][warning][os,thread] Failed to start the native thread for java.lang.Thread "pool-1-thread-4059" 平台线程(每个任务一个) 10000 个任务各 sleep 1 秒:提交到第 4059 个任务时失败:OutOfMemoryError(unable to create native thread);0.5 秒时 RSS 281 MB,总耗时 1227 ms,完成 4058 个 固定 200 个线程的线程池 10000 个任务各 sleep 1 秒:0.5 秒时 RSS 184 MB,总耗时 50358 ms,完成 10000 个
创建 + 启动 + join 一个线程的平均耗时:虚拟线程 6 µs(100000 个),平台线程 36 µs(10000 个) 20 个纯计算任务(核数的 2 倍):虚拟线程 总耗时 868 ms 20 个纯计算任务(核数的 2 倍):平台线程 总耗时 855 ms