英文:
How does polling with thread.sleep() work?
问题
以下是翻译好的部分:
我不明白为什么输出仅打印一次“Not reached yet”,而不是每次计数器小于100时都打印一次。我期望输出会打印“Not reached yet”100次,然后打印“Reached”。
英文:
I am new to threads in Java, I am trying to understand how they work; considering the following code:
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!");
}
}
The output of the above code:
Not reached yet
Reached!
I don't understand why the output prints "Not reached yet" just once, and not for every time counter is less than a 100. I was expecting the output to print "Not reached yet" a 100 then print "Reached"?
答案1
得分: 3
"我不明白为什么输出仅在计数器小于100时打印一次"尚未到达",而不是每次计数器小于100时都打印一次。 " - 实际上是这样的!但是,ZooInfo.counter
的值仅在每秒钟检查一次。启动的线程(new Thread(() -> { for(int i=0; i<500; i++) ZooInfo.counter++; }).start();
)在前100次迭代中所需的时间明显少于一秒。删除Thread.sleep(...)
并不一定会改变行为(对我来说,它会导致Not yet reached!
被打印1-3次)。这是由于新创建的线程仍然领先。此外,这两个线程不会"同步运行",即一个线程可能比另一个线程更快或更慢。
此外,正如@Amongalen和@Polygnome所指出的,向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!"的次数。
备注:字段private static int counter = 0;
还应该声明为volatile
,以确保线程之间有适当的可见性。
英文:
"I don't understand why the output prints "Not reached yet" just once, and not for every time counter is less than a 100." - It does! The value of ZooInfo.counter
, however, is only checked once a second. The thread started (new Thread(() -> { for(int i=0; i<500; i++) ZooInfo.counter++; }).start();
will take significantly less than a second for the first 100 iterations. Removing the Thread.sleep(...)
does not necessarily change the behaviour (for me, it leads to Not yet reached!
being printend 1-3 times). This is due to the fact that the newly created thread still has a head start. Also, the two threads do not run "in unison", i.e. one thread may proceed faster or slower than the other.
Furthermore, as was pointed out by @Amongalen and @Polygnome, printing to System.out
is slow. We can improve this by using a 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());
This will increase the number of times Not reached yet!
is printed.
A remark: the field private static int counter = 0;
should also be declared volatile
to guarantee proper visibility between threads.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论