资讯专栏INFORMATION COLUMN

Java多线程基础(七)——Producer-Consumer模式

Benedict Evans / 1813人阅读

摘要:一定义就是生产者消费者模式。消费者参与者从参与者获取数据,进行处理。通道参与者从参与者处接受参与者,并保管起来,并应参与者的要求,将参与者传送出去。为确保安全性,参与者与参与者要对访问共享互斥。

一、定义

Producer-Consumer Pattern就是生产者-消费者模式。
生产者和消费者在为不同的处理线程,生产者必须将数据安全地交给消费者,消费者进行消费时,如果生产者还没有建立数据,则消费者需要等待。
一般来说,可能存在多个生产者和消费者,不过也有可能生产者和消费者都只有一个,当双方都只有一个时,我们也称之为Pipe Pattern

二、模式案例

该案例中,定义了3个角色:厨师、客人、桌子。

厨师(生产者)定义:

public class MakerThread extends Thread {
    private final Random random;
    private final Table table;
    private static int id = 0;     //蛋糕的流水号(所有厨师共通)
    public MakerThread(String name, Table table, long seed) {
        super(name);
        this.table = table;
        this.random = new Random(seed);
    }
    public void run() {
        try {
            while (true) {
                Thread.sleep(random.nextInt(1000));
                String cake = "[ Cake No." + nextId() + " by " + getName() + " ]";
                table.put(cake);
            }
        } catch (InterruptedException e) {
        }
    }
    private static synchronized int nextId() {
        return id++;
    }
}

客人(消费者)定义:

public class EaterThread extends Thread {
    private final Random random;
    private final Table table;
    public EaterThread(String name, Table table, long seed) {
        super(name);
        this.table = table;
        this.random = new Random(seed);
    }
    public void run() {
        try {
            while (true) {
                String cake = table.take();
                Thread.sleep(random.nextInt(1000));
            }
        } catch (InterruptedException e) {
        }
    }
}

桌子(队列)定义:

public class Table {
    private final String[] buffer;
    private int tail;
    private int head;
    private int count;
 
    public Table(int count) {
        this.buffer = new String[count];
        this.head = 0;
        this.tail = 0;
        this.count = 0;
    }
    public synchronized void put(String cake) throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " puts " + cake);
        while (count >= buffer.length) {
            wait();
        }
        buffer[tail] = cake;
        tail = (tail + 1) % buffer.length;
        count++;
        notifyAll();
    }
    public synchronized String take() throws InterruptedException {
        while (count <= 0) {
            wait();
        }
        String cake = buffer[head];
        head = (head + 1) % buffer.length;
        count--;
        notifyAll();
        System.out.println(Thread.currentThread().getName() + " takes " + cake);
        return cake;
    }
}

执行:

public class Main {
    public static void main(String[] args) {
        Table table = new Table(3);
        new MakerThread("MakerThread-1", table, 31415).start();
        new MakerThread("MakerThread-2", table, 92653).start();
        new MakerThread("MakerThread-3", table, 58979).start();
        new EaterThread("EaterThread-1", table, 32384).start();
        new EaterThread("EaterThread-2", table, 62643).start();
        new EaterThread("EaterThread-3", table, 38327).start();
    }
}
三、模式讲解

Producer-Consumer模式的角色如下:

Data(数据)参与者

Data代表了实际生产或消费的数据。

Producer(生产者)参与者

Producer会创建Data,然后传递给Channel参与者。

Consumer(消费者)参与者

Consumer从Channel参与者获取Data数据,进行处理。

Channel(通道)参与者

Channel从Producer参与者处接受Data参与者,并保管起来,并应Consumer参与者的要求,将Data参与者传送出去。为确保安全性,Producer参与者与Consumer参与者要对访问共享互斥。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71514.html

相关文章

  • Java线程进阶(三一)—— J.U.C之collections框架:BlockingQueue接

    摘要:和方法会一直阻塞调用线程,直到线程被中断或队列状态可用和方法会限时阻塞调用线程,直到超时或线程被中断或队列状态可用。 showImg(https://segmentfault.com/img/bVbgyPy?w=1191&h=670); 本文首发于一世流云专栏:https://segmentfault.com/blog... 一、引言 从本节开始,我们将介绍juc-collectio...

    entner 评论0 收藏0
  • 亿级高并发系统的监控与报警

    摘要:个巡个推系统监控随着个推业务的不断扩展,用户量不断的增加,个推急需一套完整的监控系统来实时保证系统和业务的正常运转。系统难点与设计多元化的数据基于推送业务,个推扩展出许多独立运行的系统,而且每个系统的监控数据也不一样。 什么是系统监控对于功能简单,用户量较少的软件系统,大部分公司不需要额外的监控系统来保证公司业务的正常运行。而当公司发展到一定程度,系统越来越多元化,单一系统也越来越复杂...

    lovXin 评论0 收藏0
  • 【全栈之路】JAVA基础课程四_生产者消费者问题(20190614v1.1)

    摘要:寄语天眼之父南仁东,心无旁骛,为崇山峻岭间的中国天眼燃尽生命,看似一口大锅,天眼是世界上最大最灵敏的单口径射电望远镜,可以接受百亿光年外的电磁信号。南仁东总工程师执着追求科学梦想的精神,将激励一代又一代科技工作者继续奋斗,勇攀世界科技高峰。 欢迎进入JAVA基础课程 博客地址:https://segmentfault.com/a/11...本系列文章将主要针对JAVA一些基础知识点进行...

    lemon 评论0 收藏0
  • 【全栈之路】JAVA基础课程四_生产者消费者问题(20190614v1.1)

    摘要:寄语天眼之父南仁东,心无旁骛,为崇山峻岭间的中国天眼燃尽生命,看似一口大锅,天眼是世界上最大最灵敏的单口径射电望远镜,可以接受百亿光年外的电磁信号。南仁东总工程师执着追求科学梦想的精神,将激励一代又一代科技工作者继续奋斗,勇攀世界科技高峰。 欢迎进入JAVA基础课程 博客地址:https://segmentfault.com/a/11...本系列文章将主要针对JAVA一些基础知识点进行...

    everfight 评论0 收藏0
  • Java学习路线总结,搬砖工逆袭Java架构师(全网最强)

    摘要:哪吒社区技能树打卡打卡贴函数式接口简介领域优质创作者哪吒公众号作者架构师奋斗者扫描主页左侧二维码,加入群聊,一起学习一起进步欢迎点赞收藏留言前情提要无意间听到领导们的谈话,现在公司的现状是码农太多,但能独立带队的人太少,简而言之,不缺干 ? 哪吒社区Java技能树打卡 【打卡贴 day2...

    Scorpion 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<