1.Problem Descrption:
知识背景1:需要对操作系统中的消费者-生产者问题有一定的理解,在这里不再进行讲解了,大家可以百度或者查阅相应的书籍。
知识背景2:Java多线程的相关知识。
下面就直接上代码了!!!
2.Code:
2.1 BreadContainer类
package producer.and.consumer;
//面包容器类
public 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 producerName) {
//判断是否可以继续生产面包
//如果当前面包数量 + 生产的面包数量 > 面包厂的最大生产量
while(num + produceNum > maxNum) {
//打印相关信息
System.out.println(producerName + "要生产" + produceNum + "个,当前有"
+ num + "个,资源充足,不需要生产," + producerName + "去等待!");
try {
//此时无需生产 所以生产者等待
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
//满足条件后,生产者可以生产面包,数量 = 当前面包数量 + 生产者生产的面包数量
num = num + produceNum;
//打印相关信息
System.out.println(producerName + "生产了" + produceNum
+ "个,现在有" + num + "个!");
//此时唤醒资源等待池中的所有线程
notifyAll();
}
//同步方法
public synchronized void consumeBread(int consumeNum,String consumerName) {
//判断面包数量是否满足消费
//如果所需消费的面包数量 > 当前面包数量
while(consumeNum > num) {
//打印相关信息
System.out.println(consumerName + "要消费" + consumeNum + "个,由于现在只有"
+ num + "个," + consumerName + "于是去等待!");
try {
//数量不够,不能满足消费,所以消费者等待
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
//满足条件后,数量充足,消费面包,数量 = 当前面包数量 - 所需消费的面包数量
num = num - consumeNum;
//打印相关信息
System.out.println(consumerName + "消费了" + consumeNum
+ "个,现在还剩下" + num + "个!");
//此时唤醒资源等待池中的所有线程
this.notifyAll();
}
}
2.2 Producer类
package producer.and.consumer;
//生产者类继承了Thread类
public class Producer extends Thread{
//生产者一次生产的面包数量
private int produceNum;
//生产者需要访问的面包容器数量
private BreadContainer bc;
//无参构造方法
public Producer() {
}
//有参构造方法
public Producer(int produceNum,BreadContainer bc,String producerName) {
//对生产者线程中的某些资源进行初始化
this.produceNum=produceNum;
this.bc=bc;
this.setName(producerName);
}
//生产者的生产方法
@Override
public void run() {
bc.produceBread(produceNum,this.getName());
}
}
2.3 Consumer类
package producer.and.consumer;
//消费者类继承了Thread类
public class Consumer extends Thread{
//记录消费者一次消费的数量
private int consumeNum;
//消费者需要访问的面包容器数量
private BreadContainer bc;
//无参构造方法
public Consumer() {
}
//有参构造方法
public Consumer(int consumeNum,BreadContainer bc,String consumerName) {
//对消费者线程中的某些资源进行初始化
this.consumeNum=consumeNum;
this.bc=bc;
this.setName(consumerName);
}
//消费者的消费方法
@Override
public void run() {
bc.consumeBread(consumeNum,this.getName());
}
}
2.4 Main主类
package producer.and.consumer;
//Main主类
public class Main {
public static void main(String[] args) {
//实例化一个面包容器类的对象,即初始面包数量为50
BreadContainer bc=new BreadContainer(50);
//创建相应的生产者和消费者线程对象
Producer p1=new Producer(20,bc,"p1");
Producer p2=new Producer(290,bc,"p2");
Consumer c1=new Consumer(80,bc,"c1");
Consumer c2=new Consumer(60,bc,"c2");
//调用start()方法启动生产者-消费者线程
c1.start();
c2.start();
p1.start();
p2.start();
}
}
2.5 Program running results