![](/img/trans.png)
[英]Does a virtual thread wake up in the same carrier thread on which it was blocked?
[英]Is there a way to tell what Carrier Thread a Virtual Thread is running on?
我第一次玩 Project Loom 并且我有一些代码
try (var executor = Executors.newVirtualThreadExecutor()) {
IntStream.range(0, 16).forEach(i -> {
System.out.println("i = " + i + ", Thread ID = " + Thread.currentThread());
executor.submit(() -> {
System.out.println("Thread ID = " + Thread.currentThread());
});
});
}
输出像
Thread ID = VirtualThread[#37]/runnable@ForkJoinPool-1-worker-4
Thread ID = VirtualThread[#33]/runnable@ForkJoinPool-1-worker-5
i = 9, Thread ID = Thread[#1,main,5,main]
Thread ID = VirtualThread[#43]/runnable@ForkJoinPool-1-worker-9
Thread ID = VirtualThread[#46]/runnable@ForkJoinPool-1-worker-11
i = 10, Thread ID = Thread[#1,main,5,main]
i = 11, Thread ID = Thread[#1,main,5,main]
有没有办法告诉我每个虚拟线程在哪个载体线程上运行?
ForkJoinPool-1-worker-11
代表一个特定的载体(平台)线程,还是其他什么意思?
是的,这个后缀是当前载体线程的名称。
当我使用以下代码时
public static void main(String[] args) throws InterruptedException {
Set<String> threadStrings = ConcurrentHashMap.newKeySet();
try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.invokeAll(Collections.nCopies(16,
() -> threadStrings.add(Thread.currentThread().toString())));
}
System.out.println("\tSimple Run");
threadStrings.stream().sorted().forEachOrdered(System.out::println);
threadStrings.clear();
try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.invokeAll(Collections.nCopies(16, () -> {
threadStrings.add(Thread.currentThread().toString());
Thread.sleep(100);
return threadStrings.add(Thread.currentThread().toString());
}));
}
System.out.println("\tWith wait");
threadStrings.stream().sorted().forEachOrdered(System.out::println);
}
它打印
Simple Run
VirtualThread[#15]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#17]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#18]/runnable@ForkJoinPool-1-worker-3
VirtualThread[#19]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#20]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#21]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#22]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#23]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#24]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#25]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#26]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#27]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#28]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#29]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#30]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#31]/runnable@ForkJoinPool-1-worker-4
With wait
VirtualThread[#36]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#37]/runnable@ForkJoinPool-1-worker-3
VirtualThread[#37]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#38]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#38]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#39]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#39]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#40]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#40]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#41]/runnable@ForkJoinPool-1-worker-6
VirtualThread[#41]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#42]/runnable@ForkJoinPool-1-worker-7
VirtualThread[#42]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#43]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#43]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#44]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#44]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#45]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#45]/runnable@ForkJoinPool-1-worker-6
VirtualThread[#46]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#46]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#47]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#49]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#49]/runnable@ForkJoinPool-1-worker-8
VirtualThread[#50]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#50]/runnable@ForkJoinPool-1-worker-6
VirtualThread[#51]/runnable@ForkJoinPool-1-worker-3
VirtualThread[#51]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#52]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#52]/runnable@ForkJoinPool-1-worker-8
(结果可能会有所不同)
演示在执行sleep
时载体线程可能如何变化。 但是在当前的快照(“build 18-loom+6-282”)中,不能再指定你自己的Executor
并且没有方法可以查询关于它使用的载体线程的虚拟线程(除了通过toString()
的隐式提示) toString()
)。 所以,底层宿主线程的管理在这个版本中多半是黑盒子。
请记住,这是一个持续的发展。 目前尚不清楚这是否以及如何改变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.