基于数组的形式实现了生产者与消费者的模型,代码如下:
public class ConsumerAndProducer {
final Object[] items;// 生产队列
int putIndex; //生产者指针
int takeIndex; //消费者指针
int count;//产品总数
final ReentrantLock lock;//锁
private final Condition notEmpty; //对应消费者的condition
private final Condition notFull; //对应生产者的condition
public ConsumerAndProducer(int capacity, boolean fair) {
this.items = new Object[capacity];
this.putIndex = 0;
this.takeIndex = 0;
this.count = 0;
this.lock = new ReentrantLock(fair);
this.notEmpty = lock.newCondition();
this.notFull = lock.newCondition();
}
//生产产品
public void put(Object obj) {
//加锁保证线程安全
lock.lock();
//先判断此时生产队列是否已满
try {
while (count == items.length) {
//阻塞生产者线程
notFull.await();
}
System.out.println("正在生产第" + putIndex + "个商品");
items[putIndex] = obj;
//在越界时重置
if (++putIndex == items.length) putIndex = 0;
count++;
//唤醒消费者线程
notEmpty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁,防止死锁
lock.unlock();
}
}
//消费者消费产品
public Object take() {
lock.lock();
Object obj = null;
try {
while (count == 0) {
//阻塞消费者线程
notEmpty.await();
}
System.out.println("正在消费第" + takeIndex + "个商品");
obj = items[takeIndex];
items[takeIndex] = null;
if(++takeIndex == items.length) takeIndex = 0;
count--;
//唤醒消费者进程
notFull.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
return obj;
}
}
}
class Producer implements Runnable{
ConsumerAndProducer consumerAndProducer;
public Producer(ConsumerAndProducer consumerAndProducer) {
this.consumerAndProducer = consumerAndProducer;
}
@Override
public void run() {
try {
for(int i =0; ; ) {
//Thread.sleep(1);
consumerAndProducer.put(new Object());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable{
ConsumerAndProducer consumerAndProducer;
public Consumer(ConsumerAndProducer consumerAndProducer) {
this.consumerAndProducer = consumerAndProducer;
}
@Override
public void run() {
try {
for(int i = 0; ; ) {
Thread.sleep(1);
consumerAndProducer.take();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试:
@Test
public void test5() {
ConsumerAndProducer cap = new ConsumerAndProducer(50, false);
Producer p = new Producer(cap);
Consumer c = new Consumer(cap);
new Thread(p).start();
new Thread(p).start();
new Thread(c).start();
new Thread(c).start();
}
输出:
正在生产第0个商品
正在生产第1个商品
正在消费第0个商品
正在消费第1个商品
正在生产第2个商品
正在生产第3个商品
正在生产第4个商品
正在生产第5个商品
正在生产第6个商品
正在生产第7个商品
正在生产第8个商品
正在生产第9个商品
正在生产第10个商品
正在生产第11个商品
正在生产第12个商品
正在生产第13个商品
正在生产第14个商品
正在生产第15个商品
正在生产第16个商品
正在生产第17个商品
正在生产第18个商品
正在生产第19个商品
正在生产第20个商品
正在生产第21个商品
正在生产第22个商品
正在生产第23个商品
正在生产第24个商品
正在生产第25个商品
正在生产第26个商品
正在生产第27个商品
正在生产第28个商品
正在生产第29个商品
正在生产第30个商品
正在生产第31个商品
正在生产第32个商品
正在生产第33个商品
正在生产第34个商品
正在生产第35个商品
正在生产第36个商品
正在生产第37个商品
正在生产第38个商品
正在生产第39个商品
正在生产第40个商品
正在生产第41个商品
正在生产第42个商品
正在生产第43个商品
正在生产第44个商品
正在生产第45个商品
正在生产第46个商品
正在生产第47个商品
正在生产第48个商品
正在生产第49个商品
正在生产第0个商品
正在生产第1个商品