生产者跟消费者实现(Java)
生产者和消费者实现(Java)
生产者和消费者是我们会经常遇到的问题,今天抽时间编写了这种场景的实现。所谓生产者就是产生某种数据的一个对象(通常是一个线程),生产者生产的数据放到一个仓库中,消费者直接从仓库中提取数据即可。所谓消费者就是从仓库中提取数据的对象,通常是另外一个线程。下面生产者生产面包,放到仓库中,供消费者使用的例子。
1. 对象说明:
Bread:生产者负责生产的面包
BreadCache:生产者生产的面包存放的仓库,也就是一个缓存地址
Producer:负责生产面包的线程,生产出的面包放到BreadCache仓库中
Consumer:负责消费面包的线程,负责从BreadCache仓库中取面包进行消费
2. 示例代码
package com.****.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(); } } } } }