Search code examples
javamultithreadingpolling

How does polling with thread.sleep() work?


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"?


Solution

  • "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.

    Ideone demo


    A remark: the field private static int counter = 0; should also be declared volatile to guarantee proper visibility between threads.