Java 多线程实现生产者消费者问题(wait/notify)
本文参考网上一些例子,使用synchronized及对象的wait/notify方法实现。
首先定义3个类,一个是容器类,属性有容器最大容量和当前容量;
另外两个分别是生产者和消费者类,二者分别有生产方法和消费方法(均在各自的run方法中实现,实际上最好抽离出来成为一个单独的方法)
package test3; class Container{ public int max; //定义容器最大容量 public int currentNum;//定义容器当前容量 public Container(int max){ this.max = max; currentNum = 0; } } class Producer implements Runnable{ public Container con; public Producer(Container con){ this.con = con; } public void run(){ while(true){//有无数个苹果 synchronized(con){ if(con.currentNum < con.max){//若当前容器不满,则可以生产 con.notify();//生产完则通知并释放锁 con.currentNum++; System.out.println(" 生产者正在生产...+1, 当前产品数:"+con.currentNum); }else if(con.currentNum == con.max){// System.out.println("箱子已经饱和,生产者停止生产,正在等待消费..."); try { con.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }//if else if }//syn 执行完同步块 释放锁,输出结果中连续出现两次生产者是因为:释放锁后,若没有等待线程,则还是先执行到哪个线程的同步块就执行它 try { Thread.sleep(100);//调节生产者频率,过快容易猝死~~ } catch (InterruptedException e) { e.printStackTrace(); }//try }//while } } class Consumer implements Runnable{ public Container con; public Consumer(Container con){ this.con = con; } public void run(){ while(true){ synchronized(con){ if(con.currentNum > 0 ){ con.notify(); con.currentNum--; System.out.println(" 消费者正在消费...-1, 当前产品数:"+con.currentNum); }else if(con.currentNum == 0){ System.out.println("箱子已经空了,消费者停止消费,正在等待生产..."); try { con.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }//else if }//syn try { Thread.sleep(140);//调节消费者频率,过快容易撑死~~ } catch (InterruptedException e) { e.printStackTrace(); }//try }//while }// run } public class TestProducerConsumer{ public static void main(String args[]){ Container container = new Container(5);//定义箱子最大容量,此处为5 Producer producer = new Producer(container);//箱子中的苹果数要同步,所以将箱子对象引用作为形参传给生产者和消费者 Consumer consumer = new Consumer(container);// new Thread(producer, "producer").start();//启动生产消费模式 new Thread(consumer, "consumer").start(); } }
程序输出:
生产者正在生产...+1, 当前产品数:1 消费者正在消费...-1, 当前产品数:0 生产者正在生产...+1, 当前产品数:1 消费者正在消费...-1, 当前产品数:0 生产者正在生产...+1, 当前产品数:1 消费者正在消费...-1, 当前产品数:0 生产者正在生产...+1, 当前产品数:1 消费者正在消费...-1, 当前产品数:0 生产者正在生产...+1, 当前产品数:1 生产者正在生产...+1, 当前产品数:2 消费者正在消费...-1, 当前产品数:1 生产者正在生产...+1, 当前产品数:2 消费者正在消费...-1, 当前产品数:1 生产者正在生产...+1, 当前产品数:2 消费者正在消费...-1, 当前产品数:1 生产者正在生产...+1, 当前产品数:2 生产者正在生产...+1, 当前产品数:3 消费者正在消费...-1, 当前产品数:2 生产者正在生产...+1, 当前产品数:3 消费者正在消费...-1, 当前产品数:2 生产者正在生产...+1, 当前产品数:3 消费者正在消费...-1, 当前产品数:2 生产者正在生产...+1, 当前产品数:3 消费者正在消费...-1, 当前产品数:2 生产者正在生产...+1, 当前产品数:3 生产者正在生产...+1, 当前产品数:4 消费者正在消费...-1, 当前产品数:3 生产者正在生产...+1, 当前产品数:4 消费者正在消费...-1, 当前产品数:3 生产者正在生产...+1, 当前产品数:4 消费者正在消费...-1, 当前产品数:3 生产者正在生产...+1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 箱子已经饱和,生产者停止生产,正在等待消费... 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 箱子已经饱和,生产者停止生产,正在等待消费... 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 箱子已经饱和,生产者停止生产,正在等待消费... 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 箱子已经饱和,生产者停止生产,正在等待消费... 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 箱子已经饱和,生产者停止生产,正在等待消费... 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5 消费者正在消费...-1, 当前产品数:4 生产者正在生产...+1, 当前产品数:5
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。