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?
signalAll()
instead ofsignal()
, are they equivalent here since only one type of threads are waiting on one condition? signalAll is only required in case using the same condition for both producer/consumer? – Busey