当运行一个从 java 的新虚拟线程调用 System.out.println 方法的示例程序时,我得到了一些奇怪的结果。这是示例程序:
import java.math.BigInteger;
import java.time.LocalDateTime;
public class VirtualThreadTest {
public static void main(String[] args) {
for(int i = 1; i <= 200; i+=1) {
Thread.ofVirtual().start(() -> {
System.out.println(LocalDateTime.now());
System.out.flush();
expensiveTask();
});
}
sleepMainThread();
}
private static void expensiveTask() {
var bi = BigInteger.ONE;
for(int i = 2; i < 50_000; i+=1) {
bi = bi.multiply(BigInteger.valueOf(i));
}
}
private static void sleepMainThread() {
try {
Thread.sleep(60_000);
} catch(Exception e) { e.printStackTrace(); }
}
}
首先程序会按升序打印当前时间,但过了一会儿它会打印过去的值,例如:
2024-05-08T14:17:34.925188363
2024-05-08T14:17:34.925920200
2024-05-08T14:17:34.925993640
2024-05-08T14:17:34.926365126
...
2024-05-08T14:17:50.927143298
2024-05-08T14:17:51.136285346
2024-05-08T14:17:34.925684196 // prints value in the past
2024-05-08T14:17:51.251390867
2024-05-08T14:17:51.309471812
有人知道为什么会发生这种情况吗?谢谢。
启动了很多虚拟线程,但有些虚拟线程并没有立即被真实线程发挥。你可以看到它的时间晚于当时最后一个虚拟线程,播放正常。
您可能会看到饥饿,即稍后的虚拟线程首先获得线程。我怀疑与可用的实际物理线程数量有关。