zoukankan      html  css  js  c++  java
  • 线程的管程法跟信号灯法_生产者消费模式

    在生产者跟消费模式中常用两种方法来处理并发问题,管程法跟信用灯法

    • 管程法:常用一个缓冲区来处理通知唤醒跟等待
    • 信号灯法:常用一个标识位来处理唤醒跟等待操作

    管程法:

      1 package 多线程练习.锁学习.生产者消费模式;
      2 
      3 public class 管程法 {
      4     public static void main(String[] args) {
      5         Syncontainer syncontainer = new Syncontainer();
      6         Producer producer = new Producer(syncontainer);
      7         Consumer consumer = new Consumer(syncontainer);
      8         new Thread(producer, "生产者").start();
      9         new Thread(consumer, "消费者").start();
     10     }
     11 }
     12 
     13 
     14 class Chicken {
     15     int id;
     16 
     17     public Chicken(int id) {
     18         this.id = id;
     19     }
     20 }
     21 
     22 class Producer implements Runnable {
     23 
     24     Syncontainer syncontainer;
     25 
     26     public Producer(Syncontainer syncontainer) {
     27         this.syncontainer = syncontainer;
     28     }
     29 
     30     @Override
     31     public void run() {
     32         for (int i = 0; i < 100; i++) {
     33             System.out.println("生产了" + i + "只鸡");
     34             syncontainer.push(new Chicken(i));
     35         }
     36     }
     37 }
     38 
     39 class Consumer implements Runnable {
     40 
     41     Syncontainer syncontainer;
     42 
     43     public Consumer(Syncontainer syncontainer) {
     44         this.syncontainer = syncontainer;
     45     }
     46 
     47     @Override
     48     public void run() {
     49         for (int i = 0; i < 100; i++) {
     50             System.out.println("消费了" + syncontainer.pop().id + "只鸡");
     51         }
     52     }
     53 }
     54 
     55 class Syncontainer {
     56     // 缓冲区最多可以存放10只鸡
     57     Chicken[] chickens = new Chicken[10];
     58     // 计数器
     59     int count = 0;
     60 
     61     // 生产者放入产品
     62     public synchronized void push(Chicken chicken) {
     63         // 判断容器内有没有产品 没有就通知生产者生产 消费者等待
     64         if (count == chickens.length) {
     65             // 里面的容量已经满了 去通知消费者消费
     66             try {
     67                 this.wait();
     68             } catch (InterruptedException e) {
     69                 e.printStackTrace();
     70             }
     71         }
     72 
     73         chickens[count] = chicken;
     74         count++;
     75 
     76 
     77         // 通知消费者消费
     78         this.notifyAll();
     79 
     80     }
     81 
     82     // 消费者消费产品
     83     public synchronized Chicken pop() {
     84         if (count == 0) {
     85             // 容器中空了 通知生产者生产 消费者等待
     86             try {
     87                 this.wait();
     88             } catch (InterruptedException e) {
     89                 e.printStackTrace();
     90             }
     91         }
     92 
     93 
     94         count--;
     95         Chicken chicken = chickens[count];
     96 
     97         // 通知生产者生产
     98         this.notifyAll();
     99 
    100 
    101         return chicken;
    102     }
    103 }

    管程法输出结果:

    信号灯法:

    package 多线程练习.锁学习.生产者消费模式;
    
    import org.omg.CORBA.TCKind;
    
    public class 信号灯法 {
        public static void main(String[] args) {
            Tv tv = new Tv();
            Productor02 p = new Productor02(tv);
            Consumer02 c = new Consumer02(tv);
            new Thread(p).start();
            new Thread(c).start();
    
        }
    }
    
    class Productor02 implements Runnable {
        Tv tv;
    
        public Productor02(Tv tv) {
            this.tv = tv;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                if (i % 2 == 0) {
                    tv.player("还珠格格");
                } else {
                    tv.player("广告时间");
                }
            }
    
        }
    }
    
    class Consumer02 implements Runnable {
    
        Tv tv;
    
        public Consumer02(Tv tv) {
            this.tv = tv;
        }
    
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                tv.SeeTv();
            }
        }
    }
    
    class Tv {
        Boolean flag = true;  // 这就是个信号灯  // 当flag  true 电视播放 观众停止  false:电视停止 观众观看
        String tvName;
    
    
        //  观众观看
        public synchronized void SeeTv() {
    
            if (flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
    
            System.out.println("观众正在观看电视节目" + this.tvName);
    
            this.notifyAll(); // 通知player继续播放下个节目
    
            flag = !flag;
    
        }
    
    
        //电视播放
        public synchronized void player(String tvName) {
            // 观众在观看的试试 不能换台
            if (!flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            System.out.println("电视机正在播放" + tvName);
            this.tvName = tvName;  //将本地额tvname更新 防止观众看了个寂寞
    
            this.notifyAll(); // 通知player继续播放下个节目
    
            flag = !flag;
        }
    
    }

    信号灯法输出结果:

  • 相关阅读:
    C++笔记(2018/2/6)
    2017级面向对象程序设计寒假作业1
    谁是你的潜在朋友
    A1095 Cars on Campus (30)(30 分)
    A1083 List Grades (25)(25 分)
    A1075 PAT Judge (25)(25 分)
    A1012 The Best Rank (25)(25 分)
    1009 说反话 (20)(20 分)
    A1055 The World's Richest(25 分)
    A1025 PAT Ranking (25)(25 分)
  • 原文地址:https://www.cnblogs.com/wooroc/p/15810537.html
Copyright © 2011-2022 走看看