I've read about the problem on https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html.
This is what the documentation says about the two conditions:
We would like to keep waiting put threads and take threads in separate wait-sets so that we can use the optimization of only notifying a single thread at a time when items or spaces become available in the buffer. This can be achieved using two Condition instances.
I could notify a single thread using one condition since signal()
wakes up one thread:
class BoundedBuffer2 {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
condition.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
condition.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
condition.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
condition.signal();
return x;
} finally {
lock.unlock();
}
}
}
Why do we need two conditions?
A race condition is a situation in which two or more threads or processes are reading or writing some shared data, and the final result depends on the timing of how the threads are scheduled. Race conditions can lead to unpredictable results and subtle program bugs.
In computing, the producer-consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, which share a common, fixed-size buffer used as a queue.
Conditions (also known as condition queues or condition variables) provide a means for one thread to suspend execution (to "wait") until notified by another thread that some state condition may now be true.
Producer and Consumer are two separate processes. Both processes share a common buffer or queue. The producer continuously produces certain data and pushes it onto the buffer, whereas the consumer consumes those data from the buffer.
Say your buffer was empty and two threads were waiting on take
, blocked on
condition.await();
Then a thread calls put
. This will signal
the Condition
and wake up one of the take
threads. That take
thread will subsequently also signal
the Condition
, waking up the other take
thread which will loop back in blocking state since there is nothing for it to take.
That last signal
was unnecessary. That second take
thread should never have been woken up since nothing was available.
The two condition algorithm allows you to notify only those threads that are relevant.
The reason for two conditions is to differentiate between threads which are producing items into the buffer and threads which are consuming items from the buffer.
ProducingThread is bothered about notFull condition and is responsible for notEmpty condition, meaning that once it produces something, it has to raise the flag and say, 'hey, i have produced something, so it is not empty now.'
ConsumingThread is bothered about notEmpty condition and is responsible for notFull condition , meaning that once it consumes something, it has to raise the flag and say, 'hey, i have consumed something, so it is not full now.'
By having this kind of separation of threads into two different wait-sets, we can alert one thread at a time - either a producer thread from producerThread set or a consumer thread from consumerThread set. By having a single condition, we might have a producer thread to alert another producer thread, which is not necessary or relevant.
If we have a single condition, which is used by both threads, we will not be able to differentiate which threads to give chance logically, for example, 3 producer threads & 2 consumer threads are waiting for their chance - either to add/remove item. If one of the consuming thread finishes its work, suppose it signals, then it is possible that another consuming thread might get woken up, which would not be our objective.
We might have different usecases of Producer/Consumer problem-
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With