san
san

Reputation: 333

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

Upvotes: 0

Views: 596

Answers (2)

sRumu
sRumu

Reputation: 11

You can use

Thread.yeild()

instead of sleep.

If a thread desires to halt its execution to allow an opportunity for the other threads of equal priority, then we should choose the yield method.Because Thread.sleep blocks the main thread.

Upvotes: 0

Turing85
Turing85

Reputation: 20195

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

Upvotes: 3

Related Questions