• 多线程20:管程法


    解决方式1:
     
    并发协作模型"生产者/消费者模式"--->管程法
    • 生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
    • 消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
    • 缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区,生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据

    思路:
    1.首先有一个生产者,消费者、生产者只顾生产,消费者只管消费、
    2.利用了一个缓冲区,缓冲了一个10个大小的数组
    3.有个方法叫放入产品,产品丢进来的时候,我们判断一下缓冲区有没有满,如果满了的话,生产者就要等待了,
    如果没有满,就将产品放进去,放进去之后有产品了,赶紧通知消费者消费
    4.消费者就判断下能不能消费呢,有没有东西,有东西的话,我就可以直接消费,消费完了,就赶紧通知生产者生产。
    如果没有东西呢,消费者就等待。等待生产者去通知他,生产者通知了,他就可以解除等待了。
      1 package com.thread.gaoji;
      2 
      3 //测试: 生产者消费者模型-->利用缓冲区解决:管程法
      4 
      5 //生产者 , 消费者 , 产品 , 缓冲区
      6 public class TestPC {
      7 
      8     public static void main(String[] args) {
      9         SynContainer container = new SynContainer();
     10 
     11         new Productor(container).start();
     12         new Consumer(container).start();
     13     }
     14 }
     15 
     16 //生产者
     17 class Productor extends Thread {
     18     SynContainer container;
     19 
     20     public Productor(SynContainer container) {
     21         this.container = container;
     22     }
     23 
     24     //生产
     25     @Override
     26     public void run() {
     27         for (int i = 0; i < 100; i++) {
     28             container.push(new Chicken(i));
     29             System.out.println("生产了" + i + "只鸡");
     30         }
     31     }
     32 }
     33 
     34 //消费者
     35 class Consumer extends Thread {
     36     SynContainer container;
     37 
     38     public Consumer(SynContainer container) {
     39         this.container = container;
     40     }
     41 
     42     //消费
     43     @Override
     44     public void run() {
     45         for (int i = 0; i < 100; i++) {
     46             System.out.println("消费了-->" + container.pop().id + "只鸡");
     47         }
     48     }
     49 }
     50 
     51 //产品
     52 class Chicken {
     53     int id;//编号
     54 
     55     public Chicken(int id) {
     56         this.id = id;
     57     }
     58 }
     59 
     60 //缓冲区
     61 class SynContainer {
     62 
     63     //需要一个容器大小
     64     Chicken[] chickens = new Chicken[10];
     65 
     66     //容器计数器
     67     int count = 0;
     68 
     69     //生产者放入产品
     70     public synchronized void push(Chicken chicken) {
     71         //如果容器满了,就需要等待消费者消费
     72         if (count == chickens.length) {
     73             //生产者等待
     74             try {
     75                 this.wait();
     76             } catch (InterruptedException e) {
     77                 e.printStackTrace();
     78             }
     79         }
     80         //如果没有满,我们需要丢入产品
     81         chickens[count] = chicken;
     82         count++;
     83 
     84         //可以通知消费者消费了.
     85         this.notifyAll();
     86     }
     87 
     88     //消费者消费产品
     89     public synchronized Chicken pop() {
     90         //判断能否消费
     91         if (count == 0) {
     92             //消费者等待
     93             try {
     94                 this.wait();
     95             } catch (InterruptedException e) {
     96                 e.printStackTrace();
     97             }
     98         }
     99 
    100         //如果可以消费
    101         count--;
    102         Chicken chicken = chickens[count];
    103 
    104         //吃完了,通知生产者生产
    105         this.notifyAll();
    106         return chicken;
    107     }
    108 }

  • 相关阅读:
    .NET经销商实战(七)——获取商品类型接口开发
    .gitignore规则不生效
    .NET经销商实战(五)——linq分页查询
    .NET经销商实战(十)——根据物品小类筛选数据
    .NET经销商实战(十二)——优化用户体验,完善产品列表查询
    .NET经销商实战(八)——前端界面代码改造
    .NET经销商实战(三)——md5加密,反射注入仓储与服务,及生成token
    Ubuntu 22.04 MacOS Monterey 主题
    Dart 语言之旅
    Docker storage drivers
  • 原文地址:https://www.cnblogs.com/duanfu/p/12260806.html
Copyright © 2020-2023  润新知