Manuel
Manuel

Reputation: 2391

Thread stuck busy waiting under some circumstances and not under others

I'm having a pretty weird problem with a java thread busy-waiting.

I have one thread that busy waits on the state of a static variable of some other thread. Let's say the thread that busy waits is waiting for another thread's static int variable to reach a certain value

while(OtherThread.countInt < 5);

If I use the above code, the thread will be stuck busy-waiting and will not break out of the while loop, even if static int countInt does reach 5.

while(OtherThread.countInt < 5) {
    // waste some time doing meaningless work
}

If I use this other code, however, then the thread does break out of the busy-wait loop. Sometimes, as soon as countInt reaches 5, other times a little while after. But it happens. For my particular example, I used this as the "meaningless work"

print("busy waiting...",1000) // wasting time doing meaningless work

where I defined print as synchronzied static void print(String s, int n) that prints string s and then sleeps for n milliseconds.

What gives? Why does the thread get stuck busy waiting on the first code, but not on the other? All threads have same priorities, so it can't be a priority issue.

Upvotes: 1

Views: 499

Answers (1)

dimo414
dimo414

Reputation: 48874

countInt isn't volatile, therefore the change isn't guaranteed to be visible to the waiting thread.

Since your print() method is synchronized it's likely creating a sufficient memory barrier that the updated value becomes visible to your while loop. This is essentially a coincidence; the while conditional itself is still broken. That's why it's so important to properly design and test concurrent code - it's easy to write something that only appears to work as intended, but will fail later (e.g. under load, on a different processor, after a seemingly-safe refactoring, etc.).

Use a proper memory barrier, such as a synchronised read and write, a volatile field, or a cross-thread communcation mechanism such as those in java.util.concurrent. There are a number of related questions exploring volatile and these other tools.

You'd also do well to study Java's concurrency support. Cross-thread communication is non-trivial.

Upvotes: 3

Related Questions