多线程-Java的经典实现-生产者和消费者模式

一句话导读

        多线程实践中,最经典的就是生产者和消费者模式,多个生产者生产产品,由多个消费者消费产品。

目录

一句话导读

一、什么是生产者和消费者模式

二、模拟实现生产者消费者模式

1.场景描述

2.代码实现

        需求分析:

1.面包对象:

2.工人对象:

3.消费者对象:

4.商店类:

 5.主方法:

3.运行结果


一、什么是生产者和消费者模式

        生产者和消费者模式是一种经典的并发编程模式,用于解决生产者和消费者之间的生产和消费问题。在该模式中,生产者负责生产数据并将数据放入共享的缓冲区(或队列)中,而消费者则负责从缓冲区中取出数据并进行消费。生产者和消费者之间通过共享的缓冲区进行通信,但彼此之间并不直接进行通信。

二、模拟实现生产者消费者模式

1.场景描述

        模拟一个场景,多个生产即面包工人一直在生产面包,然后将面包放到商店里售卖,多个消费者即顾客到商店购买面包,有多少买多少。

2.代码实现

        需求分析:

  • 要有多个工人,并且会一直生产面包
  • 要有商店放面包,并且能够接受面包的寄售和面包的售出
  • 要有多个消费者,他们能够一直在商店购买面包
  • 有个主方法,启动工厂生产面包,组织消费者去购买面包

通过以上分析,我们抽象出对应的对象:

1.面包对象:

有名称、类型等自己的特征

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Bread {
    private String name;
}

2.工人对象:

有名字等自己的属性,并有生产面包的能力,将面包放到商店货柜

import lombok.Data;

import java.util.UUID;

/**
 * 生产者对象
 */
@Data
public class BreadProducer implements Runnable {
    // 生产者名称
    private final String producerName;

    public BreadProducer(String producerName) {
        this.producerName = producerName;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Bread bread = new Bread(Thread.currentThread().getName(), UUID.randomUUID().toString());
                //每个人生产的面包都放到商店货柜上寄售
                BreadStore.put(bread);
                System.out.println(Thread.currentThread().getName() + "生产了面包,现在库存有:" + BreadStore.BREAD_STORE.size());
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3.消费者对象:

有编号、名称等自己的属性,并有购买面包的能力

/**
 * 消费者对象
 */
public class BreadConsumer implements Runnable {

    private final String name;

    public BreadConsumer(String name) {
        this.name = name;
    }


    @Override
    public void run() {
        while (true) {
            try {
                //去商店购买面包
                Bread bread = BreadStore.take();
                Thread.sleep(100);
                System.out.println(name + "购买了" + bread.getName() + ":" + bread.getId() + "面包");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
    }
}

4.商店类:

有个货柜,能寄售面包,能够卖面包

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class BreadStore {
    //要有货柜放面包,货柜只能放10个面包
    public static final BlockingQueue<Bread> BREAD_STORE = new LinkedBlockingQueue<>(10);

    //寄售面包
    public static void put(Bread bread) {
        try {
            BREAD_STORE.put(bread);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //售出面包
    public static Bread take() {
        try {
            return BREAD_STORE.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 5.主方法:

设置3个工人生产,3个消费者消费

public class MainProcess {

    public static void main(String[] args) {
        //三个人一起开始生产面包
        Thread breadProducerZhangsan = new Thread(new BreadProducer("张三"));
        Thread breadProducerLisi = new Thread(new BreadProducer("李四"));
        Thread breadProducerWangwu = new Thread(new BreadProducer("王五"));
        breadProducerZhangsan.setName("breadProducerZhangsan");
        breadProducerLisi.setName("breadProducerLisi");
        breadProducerWangwu.setName("breadProducerWangwu");
        breadProducerZhangsan.start();
        breadProducerLisi.start();
        breadProducerWangwu.start();

        //三个个消费者去商店购买面包
        Thread breadConsumer1 = new Thread(new BreadConsumer("消费者1"));
        breadConsumer1.setName("breadConsumer1");
        breadConsumer1.start();
        Thread breadConsumer2 = new Thread(new BreadConsumer("消费者2"));
        breadConsumer2.setName("breadConsumer2");
        breadConsumer2.start();
        Thread breadConsumer3 = new Thread(new BreadConsumer("消费者3"));
        breadConsumer3.setName("breadConsumer3");
        breadConsumer3.start();
    }
}

3.运行结果

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值