/**
* 生产者消费者问题
* 思路:
* 整体分析,面向对象的思维,应该几个类
* Producer 生产者类,因为要进行加工过程,所以使用线程来进行编写
* Consumer 消费者类, 因为要实现自动消费过程,所以使用多线程完成
* Basket 箩筐类, 因为要使用该类进行存取产品,多以要对该类实现线程锁, 因为箩筐存放物品数量有限制,所以要进行处理
* SteamedBun 馒头类
*/
class TestProducerConsumer
{
public static void main(String[] args)
{
Basket basket = new Basket(10); // 创建一个存放10个馒头的箩筐
new Thread(new Producer("张三", basket)).start(); // 创建一个生产者并启动生产
new Thread(new Producer("李四", basket)).start(); // 创建一个生产者并启动生产
new Thread(new Consumer("王五", basket)).start(); // 创建一个消费者类并启动消费
new Thread(new Consumer("赵六", basket)).start(); // 创建一个消费者类并启动消费
}
}
/**
* 箩筐类
* 成员属性: 馒头数组, 指向箩筐中空位置的指针
* 成员方法: 增加馒头
* 删除馒头
*/
class Basket {
private SteamedBun[] steamedBuns;
private int index = 0;
/**
* 构造函数
* @param number 该箩筐中能够存放多少馒头
*/
public Basket(int number) {
steamedBuns = new SteamedBun[number];
}
/**
* 放入一个馒头
* @param steamedBun 要放入的一个馒头对象
* 注意:
* 1. 馒头存放数量,根据构造函数中number的值进行确定,超出后将进入休眠状态
*/
public synchronized void push(SteamedBun steamedBun) {
// index总指向存放馒头的上一个位置
while(index >= steamedBuns.length) {
try{
this.wait(); // 进入线程等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll(); // 唤醒等待的所有线程
//index ++; // 使指针自增1
System.out.print("Index = " + index);
steamedBuns[ index++ ] = steamedBun;
}
/**
* 放入一个馒头
* @param steamedBun 要放入的一个馒头对象
* 注意:
* 1. 馒头存放数量,根据构造函数中number的值进行确定,超出后将进入休眠状态
*/
public void push1(SteamedBun steamedBun) {
// index总指向存放馒头的上一个位置
synchronized (this) {
while(index >= steamedBuns.length) {
try{
this.wait(); // 进入线程等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll(); // 唤醒等待的所有线程
//index ++; // 使指针自增1
System.out.print("Index = " + index);
steamedBuns[ index++ ] = steamedBun;
}
}
/**
* 从箩筐中拿出一个馒头
* 注意:
* 如果指针指向0位置就说明没有馒头了,所以将进入休眠状态,有馒头后将会唤醒
*/
public synchronized SteamedBun pop() {
while(index <= 0) {
try{
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return steamedBuns[--index];
}
/**
* 从箩筐中拿出一个馒头
* 注意:
* 如果指针指向0位置就说明没有馒头了,所以将进入休眠状态,有馒头后将会唤醒
*/
public SteamedBun pop1() {
synchronized (this) {
while(index <= 0) {
try{
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return steamedBuns[ --index];
}
}
}
/**
* 馒头类
* 成员属性: 馒头的id
* 成员方法:
* 获得馒头的id
* 设置馒头的id
*/
class SteamedBun {
private int id = 0; // 每个馒头都有一个ID
public SteamedBun(int id) {
this.id = id;
}
/**
* 设置这个馒头的ID
* @param id 要设置馒头的ID
*/
public void setId(int id) {
this.id = id;
}
/**
* 获得这个馒头的ID
* @return 要获取馒头的ID
*/
public int getId() {
return this.id;
}
}
/**
* 生产者的类,详细见类内部注释
*/
class Producer implements Runnable{
private static int id; // 制作出馒头的id
private Basket basket; // 要将产品存放在哪里
/**
* 如果要将该生产者的线程停止,请设置为false
*/
public boolean flat = true;
private String name; // 生产者的姓名
/**
* 构造方法
* @param name 生产者的名字
* @param basket 产品仓库
*/
public Producer(String name, Basket basket) {
this.name = name;
this.basket = basket;
}
/**
* 线程方法
*/
public void run() {
while (flat) {
SteamedBun steamedBun = new SteamedBun(id++); // 创建一个馒头
basket.push(steamedBun); // 加入到箩筐中
System.out.println(this.name + "制作了id为" + steamedBun.getId() + "的馒头!");
}
}
}
class Consumer implements Runnable {
private Basket basket; // 从哪里拿产品
/**
* 如果要将该生产者的线程停止,请设置为false
*/
public boolean flat = true;
private String name; // 消费者的姓名
/**
* 构造方法
* @param name 消费者的名字
*/
public Consumer(String name, Basket basket) {
this.name = name;
this.basket = basket;
}
/**
* 线程方法
*/
public void run() {
while(flat) {
SteamedBun steamedBun = basket.pop(); // 从篮子中拿出一个馒头
System.out.println(this.name + "拿出了id为" + steamedBun.getId() + "的馒头!");
}
}
}
消费者和生产者问题
最新推荐文章于 2024-07-10 21:37:49 发布