生产者消费者模型就是任意个生产者和消费者线程,分别负责生产和消费。生产者负责向缓冲池中生产产品,消费者负责从缓冲池中取出产品消费。
我们需要对这种操作做什么控制呢?
(1)放和取不能同时进行
(2)生产者不能向满了的缓冲池放置产品,消费者不能从已经空了的缓冲池中取产品
使用BlockingQueue
第一个需求:BlockingQueue是线程安全的,内部使用ReentrantLock来控制。
第二个需求:同样是在加锁后,内部判断缓冲池的大小,如果不满足条件,就一直等待条件成立
package concurrent;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* Created by geekgao on 16-3-4.
*/
public class ProducerAndConsumer2 {
public static void main(String[] args) {
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(5);
//一个生产者和两个消费者
new Thread(new Producer2(blockingQueue)).start();
new Thread(new Consumer2(blockingQueue)).start();
new Thread(new Consumer2(blockingQueue)).start();
}
}
class Producer2 implements Runnable {
private BlockingQueue<Integer> blockingQueue;
public Producer2(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
}
public void run() {
try {
//生产20个产品
for (int i = 0;i < 20;i++) {
//当队列满了,put会自己阻塞住
blockingQueue.put(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer2 implements Runnable {
private BlockingQueue<Integer> blockingQueue;
public Consumer2(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
}
public void run() {
//一直从队列中取产品来消费
while(true) {
try {
//队列为空时take会阻塞住
System.out.println(Thread.currentThread().getName() + ":" + blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}