public class MainThread
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Queue queue = new Queue(); //定义缓冲区;
Producer producer = new Producer(queue); //生产者
Consumer consumer = new Consumer(queue); //消费者
new Thread(producer).start();
new Thread(consumer).start();
}
}
/*注意:wait notify notifyAll只能在同步方法或同步块中调用*/
class Queue //queue表示队列
{
int product = 0;
boolean bfull = false;
public synchronized void setProduct(int product)
{
if (bfull)//如果队列已满,则调用wait等待消费者取走产品
{
try
{
wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*开始放置产品到队列中*/
this.product = product;
System.out.println("Producer set product:" + product);
bfull = true;
notify();//生产产品后通知消费者取走产品
}
public synchronized void getProduct()
{
if (!bfull)//如果队列是空的,则调用wait等待生产者生产产品
{
try
{
wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*开始从队列取走产品*/
System.out.println("Consumer get product:" + product);
bfull = false;
notify();//取走产品后通知生产者继续生产产品
}
}
class Producer implements Runnable
{
Queue queue;
Producer(Queue queue)
{
this.queue = queue;
}
public void run()//生产线程
{
for (int i = 1; i <= 10; i++)
{
queue.setProduct(i);
}
}
}
class Consumer implements Runnable
{
Queue queue;
Consumer(Queue queue)
{
this.queue = queue;
}
public void run()//消费线程
{
for (int i = 1; i <= 10; i++)
{
queue.getProduct();
}
}
}
/*
* Java 生产者-消费者案例框架
*“生产者-消费者”问题的含义是,
*系统中有很多生产者和消费者并
*发工作生产者负责生产资源,消费者消耗资源。
*当消费者消费资源时,如果资源不足,则需要等待,
*反之当生产者生产资源时,若资源已满,则也需要等待。
*另外同一时刻只能有一个生产者或消费者进行操作。
*/
//面包容器(资源)
class BreadContainer
{
// 容器的最大容量
public static final int maxNum = 300;
// 当前面包的数量
private int num;
// 无参构造器
public BreadContainer()
{
}
// 有参构造器
public BreadContainer(int num)
{
// 初始化面包数量
this.num = num;
}
// 制作面包的同步方法
public synchronized void produceBread(int produceNum, String ProducerSName)
{
// 测试是否可以生产面包
while (num + produceNum > maxNum)
{
// 面包充足,生产者等待
System.out.println(ProducerSName + "要生产" + produceNum + "个,当前" + num
+ "个,资源充足,不需要生产," + ProducerSName + "去等待!");
try
{
wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
// 满足条件后,生产者生产面包,刷新数量
num = num + produceNum;
System.out.println(ProducerSName + "生产了" + produceNum + "个,现在有" + num
+ "个。");
// 唤醒资源等待池中的所有线程
notifyAll();
}
public synchronized void consumeBread(int consumeNum, String ConsumerSName)
{
// 测试面包数量是否够消费
while (consumeNum > num)
{
// 不够数量,消费者等待
System.out.println(ConsumerSName + "要消费" + consumeNum + "个,由于现在只有"
+ num + "个," + ConsumerSName + "于是去等待!");
try
{
wait();
}
catch (Exception e)
{
e.printStackTrace();
}
}
// 数量充足,消费面包,刷新数量
num = num - consumeNum;
System.out.println(ConsumerSName + "消费了" + consumeNum + "个,现在还剩下" + num
+ "个");
// 唤醒资源等待池中的所有线程
this.notifyAll();
}
}
// 生产者类
class ProducerS extends Thread
{
// 记录该生产者一次生产的数量
private int produceNum;
// 生产者需要访问的面包容器资源
private BreadContainer bc;
// 无参构造器
public ProducerS()
{
}
// 有参构造器
public ProducerS(int produceNum, BreadContainer bc, String ProducerSName)
{
// 对线程进行初始化
this.produceNum = produceNum;
this.bc = bc;
this.setName(ProducerSName);
}
// 生产者的工作方法
public void run()
{
// 调用资源容器的同步方法生产资源
bc.produceBread(produceNum, this.getName());
}
}
// 消费者类
class ConsumerS extends Thread
{
// 记录该消费者一次消费的数量
private int consumeNum;
// 消费者需要访问的面包容器资源
private BreadContainer bc;
// 无参构造器
public ConsumerS()
{
}
// 有参构造器
public ConsumerS(int consumeNum, BreadContainer bc, String ConsumerSName)
{
// 对线程进行初始化
this.consumeNum = consumeNum;
this.bc = bc;
this.setName(ConsumerSName);
}
// 消费者的行为方法
public void run()
{
// 调用资源容器的同步方法生产资源
bc.consumeBread(consumeNum, this.getName());
}
}
public class Sample16_9
{
public static void main(String args[])
{
// 创建资源对象,初始面包有50个
BreadContainer bc = new BreadContainer(50);
// 创建对应的生产者和消费者
ProducerS p1 = new ProducerS(50, bc, "P1");
ProducerS p2 = new ProducerS(200, bc, "P2");
ProducerS p3 = new ProducerS(290, bc, "P3");
ConsumerS c1 = new ConsumerS(70, bc, "c1");
ConsumerS c2 = new ConsumerS(80, bc, "c2");
// 启动生产者消费者线程
c1.start();
c2.start();
p1.start();
p3.start();
p2.start();
}
}