线程的管程法跟信号灯法_生产者消费模式

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

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

 

管程法:

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

}

 

信号灯法输出结果:

线程的管程法跟信号灯法_生产者消费模式

 

上一篇:原生安卓X86 TV安装配置


下一篇:Suricata6.0流表管理源码注释四:流的建立02