对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言一样,Hello World!都是最经典的例子。
实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
对于此模型,应该明确一下几点:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。
注意:1.用while判断而不用if,因为while能保证在等待中的线程被唤醒后能够先进行while判断,如果是if则不再判断,会导致错误。
2.用notifyAll而不用notify,因为notify仅通知相同类型的线程,这时,如果该类型线程处于等待则整个程序会产生死锁;如果使用notifyAll则通知了所有线程,这样总能有线程继续运行下去,程序不会产生死锁。
/**
*
* @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,暂时无法消费!