使用 thread.sleep() 进行轮询如何工作?

How does polling with thread.sleep() work?

我是 Java 中线程的新手,我想了解它们的工作原理;考虑以下代码:

public class ZooInfo {
private static int counter = 0;

public static void main(String args[]) throws InterruptedException {    

    new Thread(() -> {
        for(int i=0; i<500; i++) ZooInfo.counter++;
        }).start();
    
    while(ZooInfo.counter<100) {
        System.out.println("Not reached yet");
    Thread.sleep(1000);
    }
    
    System.out.println("Reached!");
}   
}

以上代码的输出:

Not reached yet
Reached!

我不明白为什么输出只打印一次“Not reached yet”,而不是每次计数器小于 100 时。我期望输出打印“Not reached yet”100,然后打印“达到”?

"我不明白为什么输出只打印一次“尚未到达”,而不是每次计数器都小于 100。”- 确实如此!但是,ZooInfo.counter 的值每秒只检查一次。线程启动(new Thread(() -> { for(int i=0; i<500; i++) ZooInfo.counter++; }).start(); 在前 100 次迭代中花费的时间明显少于一秒。删除 Thread.sleep(...) 不一定会改变行为(对我来说,它会导致 Not yet reached! 成为 printend 1 -3 次)。这是因为新创建的线程仍然有先机。此外,这两个线程不会 运行 “一致”,即一个线程可能比另一个线程进行得更快或更慢.

此外,正如 and 所指出的,打印到 System.out 很慢。我们可以通过使用 StringBuilder:

来改善这一点
final String lineSeparator = System.lineSeparator();
new Thread(() -> {
    for (int i = 0; i < 500; i++) ZooInfo.counter++;
}).start();

final StringBuilder builder = new StringBuilder();
while (ZooInfo.counter < 100) {
    builder.append("Not reached yet").append(lineSeparator);
}

builder.append("Reached!");
System.out.println(builder.toString());

这将增加 Not reached yet! 的打印次数。

Ideone demo


备注:还应声明字段 private static int counter = 0; volatile 以保证线程之间的适当可见性。