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