an empty queue leading to an error. Likewise, if a producer makes the queue full in-between another producer's exiting the busy-wait and calling "enqueue", then the second producer will attempt to add to a full queue leading to an error. Spin-waiting One naive approach to achieve synchronization, as alluded to above, is to use "spin-waiting", in which a mutex is used to protect the critical sections of code and busy-waiting is still used, with the lock being acquired and released in between each busy-wait check. global RingBuffer queue; // A thread-unsafe ring-buffer of tasks. global Lock queueLock; // A mutex for the ring-buffer of tasks. // Method representing each producer thread's behavior: public method producer() { while (true) { task myTask = ...; // Producer makes some new task to be added. queueLock.acquire(); // Acquire lock for initial busy-wait check. while (queue.isFull()) { // Busy-wait until the queue is non-full. queueLock.release(); // Drop the lock temporarily to allow a chance for other threads // needing queueLock to run so that a consumer might take a task. queueLock.acquire(); // Re-acquire the lock for the next call to "queue.isFull()". } queue.enqueue(myTask); // Add the task to the queue. queueLock.release(); // Drop the queue lock until we need it again to add the next task. } } // Method representing each consumer thread's behavior: public method consumer() { while (true) { queueLock.acquire(); // Acquire lock for initial busy-wait check. while (queue.isEmpty()) { // Busy-wait until the queue is non-empty. queueLock.release(); // Drop the lock temporarily to allow a chance for other threads // needing queueLock to run so that a producer might add a task. queueLock.acquire(); // Re-acquire the lock for the next call to "queue.isEmpty()". } myTask = queue.dequeue(); // Take a task off of the queue. queueLock.release(); // Drop the queue lock until we need it again to take off the next task. doStuff(myTask); // Go off and do something with the task. } } This method assures that an inconsistent state does not occur, but wastes CPU resources due to the unnecessary busy-waiting. Even if the queue is empty and producer threads have nothing to add for a long time, consumer threads are always busy-waiting unnecessarily. Likewise, even if consumers are blocked for a long time on processing their current tasks and the queue is full, producers are always busy-waiting. This is a wasteful mechanism. What is needed is a