ReentrantLock + Condition
相比wait/ notify的写法, 核心优化点是:
- 生产者做完了, 只通知消费者, 不用去通知其他生产者
- 消费者做完了, 只通知生产者, 不用去通知其他消费者
public class OnlyNotifyProducerOrConsumer {
LinkedList<String> list = new LinkedList<>();
ReentrantLock lock = new ReentrantLock();
Condition producerCondition = lock.newCondition();
Condition consumerCondition = lock.newCondition();
private synchronized void put(String val) {
try {
lock.lock();
while (list.size() == 10) {
producerCondition.await();
}
list.addLast(val);
consumerCondition.signalAll();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
private synchronized String get() {
String ret = null;
try {
lock.lock();
while (list.size() == 0) {
consumerCondition.await();
}
ret = list.pollFirst();
producerCondition.signalAll();
} catch (Exception e) {
} finally {
lock.unlock();
}
return ret;
}
public static void main(String[] args) {
OnlyNotifyProducerOrConsumer container = new OnlyNotifyProducerOrConsumer();
Thread[] producers = new Thread[3];
Thread[] consumers = new Thread[2];
for (int i = 0; i < 3; i++) {
final int index = i;
producers[i] = new Thread() {
public void run() {
for (int j = 0; j < 2; j++) {
container.put(index + "_" + j);
System.out.println("producer: " + index + "_" + j);
}
}
};
}
for (int i = 0; i < 2; i++) {
consumers[i] = new Thread() {
public void run() {
for (int j = 0; j < 3; j++) {
System.out.println("consumer: " + container.get());
}
}
};
}
for (Thread t : producers) t.start();
for (Thread t : consumers) t.start();
}
}