生产者消费者模式的简单实现

Posted bfcs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者消费者模式的简单实现相关的知识,希望对你有一定的参考价值。

实例实现:生产者生产两种商品,消费者取走两种商品

产生的问题及解决:

数据错乱---->线程同步

重复生产和重复取------>线程间的通信

线程间通信的方法

wait():调用了 wait()方法的线程进入等待池进行等待,等待池中的线程不去竞争对象锁,直到其它的线程通知,才会进入锁池

notify():随机唤醒一个在该对象上等待的线程,被唤醒的线程进行锁池,开始竞争该对锁上的锁

notifyAll():唤醒所有在该对象上等待的线程优先级高的线程有可能先竞争到对象锁只能在同步方法和同步代码块中使用

 

商品类,可以设置商品名称和品牌,有存入和取走方法

技术图片
 1 public class Goods {
 2     private String name;//名称
 3     private String brand;//品牌
 4     private boolean isFlag;//用于标识是否有商品 ,假设为true时代表有商品,false时代表没有商品
 5     public String getName() {
 6         return name;
 7     }
 8     public void setName(String name) {
 9         this.name = name;
10     }
11     public String getBrand() {
12         return brand;
13     }
14     public void setBrand(String brand) {
15         this.brand = brand;
16     }
17     public Goods(String name, String brand) {
18         super();
19         this.name = name;
20         this.brand = brand;
21     }
22     public Goods() {
23         super();
24     }
25     //编写一个赋值的方法  同步监视器为Goods类的对象
26     public synchronized void set(String name,String brand){
27         if(isFlag){//相当于isFlag==true
28             try {
29                 super.wait();//生产者线程等待
30             } catch (InterruptedException e) {
31                 // TODO Auto-generated catch block
32                 e.printStackTrace();
33             }
34         }  //当生产者线程被唤醒后从wait()之后的代码开始执行
35         //生产商品
36         this.setName(name);
37         try {
38             Thread.sleep(300);
39         } catch (InterruptedException e) {
40             // TODO Auto-generated catch block
41             e.printStackTrace();
42         }
43         this.setBrand(brand);
44         System.out.println("-------生产者线程生产了-------"+this.getBrand()+"-------"+this.getName());
45         //通知消费者
46         super.notify();
47         isFlag=true;
48     }
49     //编写一个取值的方法
50     public synchronized void get(){
51         if(!isFlag){  // 相不于isFlag==false
52             try {
53                 super.wait();
54             } catch (InterruptedException e) {
55                 // TODO Auto-generated catch block
56                 e.printStackTrace();
57             }//消费者等待
58         }//消费者线程被唤醒后从wait()之后开始执行
59         
60         System.out.println("消费者线程取走了------"+this.getBrand()+"--------"+this.getName());
61         super.notify();//通知生产者线程
62         isFlag=false;//没有商品
63     }
64     
65 }
View Code

 

生产者线程类,调用商品类的set()设置生产哪种商品

技术图片
 1 public class Producter implements Runnable{
 2     private Goods goods;
 3     public Producter(Goods goods){
 4         this.goods=goods;
 5     }
 6     @Override
 7     public void run() {
 8         //生产商品
 9         for(int i=0;i<10;i++){
10             if(i%2!=0){//奇数
11                 goods.set("小馒头", "旺仔");//调用商品类的同步方法
12             }else{
13                 goods.set("矿泉水", "娃哈哈");
14             }
15             
16         }
17     }
18 
19 }
View Code

 

消费者线程类,调用商品类的get()取走商品

技术图片
 1 public class Customer implements Runnable {
 2     private Goods goods;
 3     public Customer(Goods goods){
 4         this.goods=goods;
 5     }
 6     public void run() {
 7         for(int i=0;i<10;i++){
 8             goods.get();//调用商品类中的取值的方法
 9         }
10         
11     };
12 }
View Code

 

启动类

技术图片
 1 public class Test {
 2     public static void main(String[] args) {
 3         //创建共享资源对象
 4         Goods g=new Goods();
 5         //创建生产者线程
 6         Producter p=new Producter(g);
 7         //创建生产者线程
 8         Customer c=new Customer(g);
 9         new Thread(p).start();
10         new Thread(c).start();
11     }
12 }
View Code

------------------------------------------------------------------------------------

结果截图

 技术图片

 

以上是关于生产者消费者模式的简单实现的主要内容,如果未能解决你的问题,请参考以下文章

生产者消费者简单实现(转载)

java使用lock实现一个简单的生产者和消费者模式

用阻塞队列和线程池简单实现生产者和消费者场景

SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段

java多线程基本概述——简单生产者消费者模式

多线程生产消费模式简单实例