生产者和消费者是我们会经常遇到的问题,今天抽时间编写了这种场景的实现。所谓生产者就是产生某种数据的一个对象(通常是一个线程),生产者生产的数据放到一个仓库中,消费者直接从仓库中提取数据即可。所谓消费者就是从仓库中提取数据的对象,通常是另外一个线程。下面生产者生产面包,放到仓库中,供消费者使用的例子。
1. 对象说明:
Bread:生产者负责生产的面包
BreadCache:生产者生产的面包存放的仓库,也就是一个缓存地址
Producer:负责生产面包的线程,生产出的面包放到BreadCache仓库中
Consumer:负责消费面包的线程,负责从BreadCache仓库中取面包进行消费
2. 示例代码
package com.csdn.algorithm.producer.consumer;
/**
* 生产者和消费者示例。<BR>
* Bread:生产者负责生产的面包<BR>
* BreadCache:生产者生产的面包存放的仓库,也就是一个缓存地址<br>
*Producer:负责生产面包的线程,生产出的面包放到BreadCache仓库中<BR>
*Consumer:负责消费面包的线程,负责从BreadCache仓库中取面包进行消费<BR>
*
* @author Administrator
*
*/
public class ProducerConsumer {
/**
* 主方法
*
* @param args
*/
public static void main(String[] args) {
//调用内部类,也可以单独作为一个类文件
ProducerConsumer aInstance = new ProducerConsumer();
BreadCache currBreadCache = aInstance.new BreadCache();
Producer p = aInstance.new Producer(currBreadCache);
Consumer c = aInstance.new Consumer(currBreadCache);
// 线程
new Thread(p).start();
new Thread(c).start();
}
// 定义一个面包类,面包只有ID
class Bread {
int m_nId;
public Bread(int _id) {
super();
this.m_nId = _id;
}
public String toString() {
return this.m_nId + "";
}
}
// 定义存放生产者生产出的面包,也就是面包的缓存
class BreadCache {
private int m_nIndex = 0;
Bread[] m_oBreadCache = new Bread[10];
public BreadCache() {
super();
}
/**
*向仓库中放入一个面包,如果仓库已经满了,则等待
*
* @param _newBread
*/
public synchronized void push(Bread _newBread) {
while (m_nIndex == m_oBreadCache.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 放面包
m_oBreadCache[m_nIndex] = _newBread;
m_nIndex++;
// 通知所有等待取面包的线程
this.notifyAll();
}
/**
* 从仓库中取一个面包,如果没有面包,则等待
*
* @return
*/
public synchronized Bread pop() {
while (m_nIndex == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
m_nIndex--;
this.notifyAll();
return m_oBreadCache[m_nIndex];
}
}
// 生产者线程,一个线程只生产20个面包
class Producer implements Runnable {
BreadCache m_oCache = null;
public Producer(BreadCache _cache) {
m_oCache = _cache;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
Bread aBread = new Bread(i);
m_oCache.push(aBread);
System.out.println("生产[ " + aBread + " ]");
try {
Thread.currentThread().sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费线程,一个线程消费掉20个面包
class Consumer implements Runnable {
BreadCache m_oCache = null;
public Consumer(BreadCache _cache) {
m_oCache = _cache;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
Bread aBread = m_oCache.pop();
System.out.println("消费[ " + aBread + " ]");
try {
Thread.currentThread().sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}