zoukankan      html  css  js  c++  java
  • 生产者消费者模式的简单实现

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

    产生的问题及解决:

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

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

    线程间通信的方法

    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

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

    结果截图

     

  • 相关阅读:
    mysql 创建数据库的基本操作
    MySQL的数据类型 及注意事项
    在执行 pip install 时遇到错误:python setup.py egg_info Check the logs for full command output
    python3.8-运行jupyter 报raise NotImplementedError
    执行python 爬虫脚本时提示bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
    Python:lambda表达式和yield关键字理解与使用讲解
    百度paddle框架学习(二):使用经典VGG网络完成人脸口罩判别
    深度学习中的梯度
    C++ OpenCV学习笔记(持续更新)
    Tensorflow常见报错
  • 原文地址:https://www.cnblogs.com/bfcs/p/10702219.html
Copyright © 2011-2022 走看看