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;
        }
    
    }

    信号灯法输出结果:

  • 相关阅读:
    for循环嵌套的原理
    php for循环|求1-100之间被3整除且被5不整除的偶数
    php 1-100之间能被3整除的数字之和;
    php判断某年某月有多少天
    关系运算符
    变量
    习题5-7 使用函数求余弦函数的近似值
    习题5-6 使用函数输出水仙花数
    习题4-11 兔子繁衍问题
    习题4-9 打印菱形图案
  • 原文地址:https://www.cnblogs.com/wooroc/p/15810537.html
Copyright © 2011-2022 走看看