对于多线程程序来讲,无论任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言同样,Hello World!都是最经典的例子。java
实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。编程
对于此模型,应该明确一下几点:多线程
一、生产者仅仅在仓储未满时候生产,仓满则中止生产。编程语言
二、消费者仅仅在仓储有产品时候才能消费,仓空则等待。ide
三、当消费者发现仓储没产品可消费时候会通知生产者生产。学习
四、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。this
此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是很是重要的。 线程
注意:1.用while判断而不用if,由于while能保证在等待中的线程被唤醒后可以先进行while判断,若是是if则再也不判断,会致使错误。code
2.用notifyAll而不用notify,由于notify仅通知相同类型的线程,这时,若是该类型线程处于等待则整个程序会产生死锁;若是使用notifyAll则通知了全部线程,这样总能有线程继续运行下去,程序不会产生死锁。blog
/** * * @author Yuanyuan */ public class TestCP { public static void main(String[] args) { Base b = new Base(20); Customer1 c1 = new Customer1(b, 10); Customer1 c2 = new Customer1(b,20); Customer1 c3 = new Customer1(b,20); Producer1 p1 = new Producer1(b, 10); c1.start(); c2.start(); c3.start(); p1.start(); } } class Base { private static final int total = 100; private int current; public Base(int initSize) { this.current = initSize; } public Base() { } public synchronized void produce(int size) { while (size > total - current) { System.out.println("要生产的产品量" + size + "超出了仓库剩余容量" + (total - current) + ",暂时没法生产!"); try { this.wait(); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } } current = current + size; System.out.println("新生产了" + size + ",当前库存" + current); this.notifyAll(); } public synchronized void custum(int size) { while (size > current) { System.out.println("要消费的产品量" + size + "超出了库存" + current + ",暂时没法消费!"); try { this.wait(); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } } current = current -size; System.out.println("新消费了"+size+"当前库存"+current); this.notifyAll(); } } class Producer1 extends Thread { private Base b; private int size; public Producer1(Base b,int size) { this.b = b; this.size = size; } @Override public void run() { b.produce(size); } } class Customer1 extends Thread { private Base b; private int size; public Customer1(Base b, int size) { this.b = b; this.size = size; } @Override public void run() { b.custum(size); } }
运行结果:
新消费了10当前库存10
新生产了10,当前库存20
新消费了20当前库存0
要消费的产品量20超出了库存0,暂时没法消费!