0

I have scenario: I want to wait, until something is false. Usually takes likes 20 seconds or so.

while(foo) {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Or just go like this?

while(foo) {

}
Natan Streppel
  • 5,759
  • 6
  • 35
  • 43
Jaanus
  • 16,161
  • 49
  • 147
  • 202
  • Can you get at whatever toggles foo? If you can, Wait/Notify seems reasonable. Try very hard not to poll. With Sleep(), you get latency and wasted CPU/memory cycles, with no Sleep(), you get grossly wasted CPU/memory cycles and. quite possibly, gross latency as well, (if the box is overloaded, the thread that would set foo may not get run for a long time). – Martin James Sep 25 '12 at 12:06

5 Answers5

9

Busy waiting for 20 seconds is not a good idea - and sleeping for 5 seconds means you might miss the signal by 5 seconds. Can't you use a different way, such as a CountdownLatch:

CountDownLatch latch = new CountDownLatch(1);

//code that triggers the signal
latch.countDown();

//code that waits for the signal
try {
    latch.await();
} catch (InterruptedException e) {
    //handle interruption
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • What does the number `1` specify ? – Jaanus Sep 26 '12 at 13:48
  • 1
    `latch.await()` will wait until the countdown reaches 0. The countdown starts at the parameter passed to the constructor (in this case: 1). Every call to `latch.countdown()` decrements the countdown. For example, if you write `latch = new CountDownLatch(2);` it will need 2 calls to `latch.countDown()` before the `latch.await()` can proceed to the next instruction. – assylias Sep 26 '12 at 13:51
2

It this is just a unit test, I would use the first example. It doesn't have to be pretty.

If this is production code, you are better off using a different structure such a Condition or a Future.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

The second form is going to burn a lot of CPU cycles. It will check as fast as it can, maybe a hundred thousand times per second. That's not a good idea.

Thread.sleep() is better, a little. You still have another problem here if foo is a non-volatile field and/or this is not in a synchronized block. It is not actually guaranteed that it will ever see an update from another thread.

Use primitives in java.util.concurrent for this like CountDownLatch.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
0

For sure, the second form can not be used. That can hog the CPU and cause problems. The first form is better.

What is going to change the value?

If it is just another thread then you can consider using wait / notify or any of the concurrency constructs.

user1676688
  • 414
  • 4
  • 15
0

Does nobody like Wait/Notify any more? It's effcient, simpler than the Sleep() loop bodges and less typing than 'CountDownLatch'.,

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • 1
    You still need to write your own condition variable and check it in some kind of loop, to differentiate from a spurious wake-up (cf. http://stackoverflow.com/questions/1050592/do-spurious-wakeups-actually-happen) CountDownLatch ends up being less writing than all that, and means you won't get it wrong -- like, not making the flag `volatile` or making sure some memory barrier copies the signal to the waiting thread's memory. – Sean Owen Sep 25 '12 at 20:10