If you have nothing else to do, and just want to wait (without using CPU) until data is available, then use a blocking queue. That's exactly what it's made for, with methods like take
:
Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), waiting if necessary until an element becomes available.
If you are interesting in how this is implemented, you can take a look at the source for these classes, for example LinkedBlockingQueue#take
:
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {
notEmpty.await();
}
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
As you can see, they maintain a couple of Conditions to signal if the queue is empty or not.