Java: Is `while (true) { ... }` loop in a thread bad? What's the alternative?

Viewed 55096

Is while (true) { ... } loop in threads bad? What's the alternative?

Update; what I'm trying to to...

I have ~10,000 threads, each consuming messages from their private queues. I have one thread that's producing messages one by one and putting them in the correct consumer's queue. Each consumer thread loops indefinitely, checking for a message to appear in their queue and process it.

Inside Consumer.java:

@Override
public void run() {
    while (true) {
        Message msg = messageQueue.poll();
        if (msg != null) {
            ... // do something with the message
        }
    }
}

The Producer is putting messages inside Consumer message queues at a rapid pace (several million messages per second). Consumers should process these messages as fast as possible!

Note: the while (true) { ... } is terminated by a KILL message sent by the Producer as its last message. However, my question is about the proper way to do this message-passing...

Please see the new question, regarding this design.

12 Answers

First up, the straight answer to this problem by Dough Lea:

It is almost never a good idea to use bare spins waiting for values of variables. Use Thread.onSpinWait, Thread.yield, and/or blocking synchronization to better cope with the fact that "eventually" can be a long time, especially when there are more threads than cores on a system.

http://gee.cs.oswego.edu/dl/html/j9mm.html

Thead.onSpinWait was introduced with Java 9. It could look like this.

while (true) {
    while (messageQueue.peek() == null) {
       Thread.onSpinWait();
    }
    // do something with the message
}

By invoking this method within each iteration of a spin-wait loop construct, the calling thread indicates to the runtime that it is busy-waiting. The runtime may take action to improve the performance of invoking spin-wait loop constructions.

https://docs.oracle.com/javase/9/docs/api/java/lang/Thread.html#onSpinWait--

Although all the above answers are correct, I want to suggest this one as I came across this situation myself: You can use a flag say:

isRunning=true;
while(isRunning){
   //do Something
}

Later, make sure that isRunning is set to false after you are done reading from the buffer or data file.

Related