IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 生产者消费者问题 -> 正文阅读

[Java知识库]生产者消费者问题

一、场景

  • 假设容器中只能存放一件物品,生产者将生产出的产品放入容器,消费者将从容器产品取走消费

  • 如果容器中没有产品,则生产者将产品放入容器,,否则停止生产并等待,直到容器中的产品被消费者取走为止

  • 如果容器中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到容器中再次放入产品为止

  • 对于生产者,没有生产产品之前,要通知消费者等待。而生产了产品之后,又需要马上通知消费者消费

  • 对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品以供消费

这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间互相依赖互为条件

二、解决方法

1.管程法

生产者将生产好的数据放入缓冲区,消费者从缓冲区中拿出数据

生产者:负责生产数据的模块(可能是对象、方法、线程、进程)

消费者:负责处理数据的模块(可能是对象、方法、线程、进程)

缓冲区:消费者不能之间使用生产者生产的数据,需要通过缓冲区处理

2.信号灯法

????????来判断一个标志位flag,如果为true,就让他等待、如果为false,就让他去通知另外一个人、把两人衔接起来,就像咱们的信号灯红灯停,绿灯行,通过这样一个判断方式,只要来判断什么瑞后让他等待,什么时候将他唤醒就ok

三、代码实现

1.管程法

产品类

public class Product{
    //产品编号
    public int id;

    public Product(int id) {
        this.id = id;
    }
}

缓冲区

public class Buffer {
    //容器大小
    Product[] products = new Product[10];
    //计数器,用来判断容器容量
    int count;

    //生产者放入产品
    public synchronized void push(Product product) throws InterruptedException {
        //如果容器满了,需要等待消费者消费
        if (count == products.length){
            //通知消费者消费,通知生产者等待
            this.wait();
        }

        //如果容器没有满,生产者需要将产品放入容器
        products[count] = product;
        count++;
        //可以通知消费者进行消费了
        this.notifyAll();
    }

    //消费者消费产品
    public synchronized Product  pop() throws InterruptedException {
        //判断能否消费
        if (count == 0){
            //等待生产者生产,消费者等待
            this.wait();
        }
        //如果可以消费
        count--;
        Product product = products[count];

        //产品消费完,通知生产者生产
        this.notifyAll();
        return product;
    }
}

生产者类

public class Producer extends Thread{
    //缓冲区对象
    Buffer container;

    public Producer(Buffer container) {
        this.container = container;
    }

    //生产产品
    @SneakyThrows
    public void run(){
        for (int i = 1; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生产了第"+i+"个产品");
        }
    }
}

消费者类

public class Consumer extends Thread {
    //缓冲区对象
    Buffer container;

    public Consumer(Buffer container) {
        this.container = container;
    }

    //消费产品
    @SneakyThrows
    public void run(){
        for (int i = 1; i < 100; i++) {
            System.out.println("----->消费了第"+container.pop().id+"个产品");
        }
    }
}

测试类

public class TestPC {
    public static void main(String[] args) {
        //缓冲区对象
        Buffer buffer = new Buffer();
        //生产者对象
        new Producer(buffer).start();
        //消费者对象
        new Consumer(buffer).start();
    }
}

2.信号灯法

//测试类
public class TestPC2 {
    public static void main(String[] args) {
        Product2 product2 = new Product2();
        new Produser2(product2).start();
        new Consumer2(product2).start();
    }
}
//生产者
class Produser2 extends Thread{
    Product2 product2;

    public Produser2(Product2 product2) {
        this.product2 = product2;
    }
    @SneakyThrows
    public void run(){
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0){
                this.product2.input("面包");
            }else {
                this.product2.input("酸奶");
            }
        }
    }
}
//消费者
class Consumer2 extends Thread{
    Product2 product2;

    public Consumer2(Product2 product2) {
        this.product2 = product2;
    }
    @SneakyThrows
    public void run(){
        for (int i = 0; i < 20; i++) {
            this.product2.output();
        }
    }
}
//产品
class Product2{
    String food;
    //消费者等待 T  ;生产者等待  F
    boolean flag = true;

    //生产
    public synchronized void input(String color) throws InterruptedException {
        if (!flag){
            this.wait();
        }
        System.out.println("生产者生产"+color);
        //通知消费者消费
        this.notifyAll();
        this.food = color;
        this.flag = !this.flag;
    }

    //消费
    public synchronized void output() throws InterruptedException {
        if (flag){
            this.wait();
        }
        System.out.println("消费者消费了"+ food);
        //通知生产者生产
        this.notifyAll();
        this.flag = !this.flag;
    }

}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:09:53  更:2022-04-09 18:12:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:41:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码