一、对生产者消费者的理解
生产者消费者模式是并发、多线程编程中经典的设计模式。
简单来看,就是一个类负责生产,一个类负责消费。举例来说,一个变量,生产者不断增加这个变量,消费者不断减少这个变量。在互联网应用中,抢票机制就是应用了该模式,比如大麦网演唱会门票抢票,12306火车票抢票等。
二、代码演示
下面使用代码来举例理解:
有这样一个场景:
生产者:往一个公共的盒子里面放苹果
消费者:从公共的盒子里面取苹果
盒子:盒子的容量不能超过5
我们将使用wait() 和 notify() 通信方法实现
1.盒子代码
public class PublicBox { private int apple = 0; public synchronized void increace() { while (apple ==5) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } apple++; System. out .println("生成苹果成功!" ); notify(); } public synchronized void decreace() { while (apple ==0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } apple--; System. out.println( "消费苹果成功!" ); notify(); } public static void main(String []args) { PublicBox box= new PublicBox(); Consumer con= new Consumer(box); Producer pro= new Producer(box); Thread t1= new Thread(con); Thread t2= new Thread(pro); t1.start(); t2.start(); } }
2.生产者代码(定义十次)
public class Producer implements Runnable { private PublicBox box; public Producer(PublicBox box) { this .box = box; } @Override public void run() { for( int i=0;i<10;i++) { try { System. out .println("pro i:" +i); Thread. sleep(30); } catch (InterruptedException e) { // TODO: handle exception e.printStackTrace(); } box.increace(); } } }
3.消费者代码(同样十次)
public class Consumer implements Runnable { private PublicBox box; public Consumer(PublicBox box) { this .box = box; } @Override public void run() { for( int i=0;i<10;i++) { try { System. out .println("Con: i " +i); Thread. sleep(3000); // 这里设置跟上面30不同是为了 盒子中的苹果能够增加,不会生产一个马上被消费 } catch (InterruptedException e) { // TODO: handle exception e.printStackTrace(); } box.decreace(); } } }
4.输出如下:
pro i:0
Con: i 0
生成苹果成功!
pro i:1
生成苹果成功!
pro i:2
生成苹果成功!
pro i:3
生成苹果成功!
pro i:4
生成苹果成功!
pro i:5
消费苹果成功!
Con: i 1
生成苹果成功!
pro i:6
消费苹果成功!
Con: i 2
生成苹果成功!
pro i:7
消费苹果成功!
生成苹果成功!
pro i:8
Con: i 3
消费苹果成功!
生成苹果成功!
pro i:9
Con: i 4
消费苹果成功!
生成苹果成功!
Con: i 5
消费苹果成功!
Con: i 6
消费苹果成功!
Con: i 7
消费苹果成功!
Con: i 8
消费苹果成功!
Con: i 9
消费苹果成功!
这个只是简单地从线程的wait、nofity来实现生产者和消费者模式。目前比较流行的是使用消息队列的方法