ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-01-16 17:07:07  阅读:139  来源: 互联网

标签:tv 管程 class 信号灯 线程 void new public syncontainer


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

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

 

管程法:

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

}

 

信号灯法输出结果:

 

标签:tv,管程,class,信号灯,线程,void,new,public,syncontainer
来源: https://www.cnblogs.com/wooroc/p/15810537.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有