使用ReentrantLock和Condition实现【生产者-消费者】。
/**
* @author wzx
* @time 2017/5/8
*/
public class ProducerConsumerSolutionUsingLock {
public static void main(String[] args) throws InterruptedException {
ProducerConsumerImpl producerConsumer = new ProducerConsumerImpl();
Thread producer = new Thread(new Producer(producerConsumer));
Thread producer2 = new Thread(new Producer(producerConsumer));
Thread producer3 = new Thread(new Producer(producerConsumer));
Thread consumer = new Thread(new Consumer(producerConsumer));
Thread consumer2 = new Thread(new Consumer(producerConsumer));
producer.start();
producer2.start();
producer3.start();
consumer.start();
consumer2.start();
TimeUnit.SECONDS.sleep(3);
}
static class ProducerConsumerImpl {
private static final int CAPACITY = 10;
private final Queue<Integer> queue = new LinkedList();
private final Random theRandom = new Random();
private final ReentrantLock lock = new ReentrantLock();
private final Condition bufferNotFull = lock.newCondition();
private final Condition bufferNotEmpty = lock.newCondition();
public void put() throws InterruptedException {
lock.lock();
try {
while (true) {
while (queue.size() == CAPACITY) {
System.out.println("Buffer is full, waiting");
bufferNotEmpty.await();
}
int num = theRandom.nextInt();
boolean isAdded = queue.offer(num);
System.out.println("added " + num + " into queue");
if (isAdded) {
bufferNotFull.signalAll();
}
}
} finally {
lock.unlock();
}
}
public void get() throws InterruptedException {
lock.lock();
try {
while (true) {
while (queue.size() == 0) {
System.out.println("Buffer is empty, waiting");
bufferNotFull.await();
}
Integer num = queue.poll();
if (num != null) {
System.out.println("consumed " + num + " from queue");
bufferNotEmpty.signalAll();
}
}
} finally {
lock.unlock();
}
}
}
static class Producer implements Runnable {
private ProducerConsumerImpl producerConsumer;
public Producer(ProducerConsumerImpl producerConsumer) {
this.producerConsumer = producerConsumer;
}
@Override
public void run() {
try {
producerConsumer.put();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Consumer implements Runnable {
private ProducerConsumerImpl producerConsumer;
public Consumer(ProducerConsumerImpl producerConsumer) {
this.producerConsumer = producerConsumer;
}
@Override
public void run() {
try {
producerConsumer.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
执行结果:
added 1892544024 into queue
added -444311193 into queue
added 1942706941 into queue
added -258892878 into queue
added -1318716428 into queue
added 1574586774 into queue
added 1202469039 into queue
added 432139815 into queue
added 283938192 into queue
Buffer is full, waiting
Buffer is full, waiting
Buffer is full, waiting
consumed -1898407557 from queue
consumed 1892544024 from queue
consumed -444311193 from queue
consumed 1942706941 from queue
consumed -258892878 from queue
consumed -1318716428 from queue
consumed 1574586774 from queue
consumed 1202469039 from queue
consumed 432139815 from queue
consumed 283938192 from queue
Buffer is empty, waiting
Buffer is empty, waiting