双非本科准备秋招(20.1)—— 并发编程之生产者消费者

生产者消费者

与保护性暂停中的不同,不需要产生结果和消费结果的线程一一对应

生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据

JDK 中各种阻塞队列,采用的就是这种模式

代码实现:

        首先,设计消息队列类MessageQueue,需要指定容量capacity,用双向链表list作为容器。

        提供take方法:检查list是否是空,空的话就wait,如果不空就打印Message,并唤醒所有线程。

        提供put方法:检查list是否满了,满了的话就wait,如果不满就添加Message,并唤醒所有线程。

        可以看到,以上的写法都是使用wait和notify的模板写法。

class MessageQueue{private LinkedList<Message> list = new LinkedList<>();private int capacity;public MessageQueue(int capacity) {this.capacity = capacity;}//取public Message take(){synchronized (list){while (list.isEmpty()){try {log.debug("队列空了");list.wait();} catch (InterruptedException e) {e.printStackTrace();}}Message message = list.removeFirst();log.debug("取出来了{}", message);list.notifyAll();return message;}}//存public void put(Message message){synchronized (list){while(list.size() == capacity){try {log.debug("队列满了");list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.addLast(message);log.debug("添加了{}", message);list.notifyAll();}}
}

        设计Message类,需要一个唯一标识id,还需要一个Object类型的value值。

final class Message{private int id;private Object value;public Message(int id, Object value) {this.id = id;this.value = value;}public int getId() {return id;}public Object getValue() {return value;}@Overridepublic String toString() {return "Message{" +"id=" + id +", value=" + value +'}';}
}

         完整代码:

public class ProductAndConsumer {public static void main(String[] args) {MessageQueue q = new MessageQueue(3);for (int i = 1; i <= 5; i++){//lambda表达式必须传final的值,不能变。int id = i;new Thread(()->{q.put(new Message(id, "v"+id));}, "生产者").start();}new Thread(()->{while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Message t = q.take();}}, "消费者").start();}
}/*** 消息队列类*/
@Slf4j(topic = "c.test")
class MessageQueue{private LinkedList<Message> list = new LinkedList<>();private int capacity;public MessageQueue(int capacity) {this.capacity = capacity;}//取public Message take(){synchronized (list){while (list.isEmpty()){try {log.debug("队列空了");list.wait();} catch (InterruptedException e) {e.printStackTrace();}}Message message = list.removeFirst();log.debug("取出来了{}", message);list.notifyAll();return message;}}//存public void put(Message message){synchronized (list){while(list.size() == capacity){try {log.debug("队列满了");list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.addLast(message);log.debug("添加了{}", message);list.notifyAll();}}
}/*** Message对象,只有get方法,并且final不可继承,也不会被子类重写方法,很安全。*/
final class Message{private int id;private Object value;public Message(int id, Object value) {this.id = id;this.value = value;}public int getId() {return id;}public Object getValue() {return value;}@Overridepublic String toString() {return "Message{" +"id=" + id +", value=" + value +'}';}
}

 某次的运行结果

21:17:06 [生产者] c.test - 添加了Message{id=5, value=v5}
21:17:06 [生产者] c.test - 添加了Message{id=2, value=v2}
21:17:06 [生产者] c.test - 添加了Message{id=3, value=v3}
21:17:06 [生产者] c.test - 队列满了
21:17:06 [生产者] c.test - 队列满了
21:17:07 [消费者] c.test - 取出来了Message{id=5, value=v5}
21:17:07 [生产者] c.test - 添加了Message{id=1, value=v1}
21:17:07 [生产者] c.test - 队列满了
21:17:08 [消费者] c.test - 取出来了Message{id=2, value=v2}
21:17:08 [生产者] c.test - 添加了Message{id=4, value=v4}
21:17:09 [消费者] c.test - 取出来了Message{id=3, value=v3}
21:17:10 [消费者] c.test - 取出来了Message{id=1, value=v1}
21:17:11 [消费者] c.test - 取出来了Message{id=4, value=v4}
21:17:12 [消费者] c.test - 队列空了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/673900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【开源】基于JAVA+Vue+SpringBoot的新能源电池回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…

Excel——合并计算

1.表格的合并计算&#xff08;单张表格/多个表格&#xff09; Q&#xff1a;请统计两个表格中各商品的总销量和总销售额&#xff0c;将结果放置在下方任意位置。 A&#xff1a;选择一个需要将合并计算数据放置区域的空白单元格 选择【数据】——【合并计算】&#xff0c;【函…

秘塔科技推出AI搜索产品「秘塔AI搜索」

近日&#xff0c;国内一家人工智能科技公司&#xff08;秘塔科技&#xff09;推出了一款AI搜索产品——秘塔AI搜索&#xff0c;能够大幅提升搜索效率&#xff0c;解决日常生活、工作学习等场景中遇到的各类搜索需求。 秘塔AI搜索官网&#xff1a;https://metaso.cn/ 相较于传统…

前端文件下载的多种方式

前端文件下载的多种方式。 前言a标签下载a标签常用属性介绍- target&#xff0c;href&#xff0c;download。 window.location.href下载window.open下载iframe 下载动态生成a标签下载文件url下载文件流下载blob文件流转换常用类型 使用 streamSaver 看实时下载进度 前言 如果我…

B站UP主实时信息获取展示php源码

B站UP主实时数据展示系统 - PHP源码分享 想要实时追踪你心仪的B站UP主的最新动态吗&#xff1f;现在&#xff0c;你可以轻松获取并展示B站UP主的实时数据&#xff0c;包括粉丝数、作品数、头像、播放量等关键信息。 功能亮点&#xff1a; 实时更新&#xff1a;系统通过B站AP…

航芯ACM32G103开发板评测 08 ADC Timer外设测试

航芯ACM32G103开发板评测 08 ADC Timer外设测试 1. 软硬件平台 ACM32G103 Board开发板MDK-ARM Keil 2. 定时器Timer 在一般的MCU芯片中&#xff0c;定时器这个外设资源是非常重要的&#xff0c;一般可以分为SysTick定时器&#xff08;系统滴答定时器&#xff09;、常规定时…

CTF秀 ctfshow WEB入门 web1-10 wp精讲

目录 web1_查看源码 web3_抓包 web4-9_目录文件 web10_cookie web1_查看源码 ctrlu 查看源码 web3_抓包 查看源码&#xff0c;无果 抓包&#xff0c;找到flag web4-9_目录文件 GitHub - maurosoria/dirsearch: Web path scanner 下载dirsearch工具扫一下就都出来了 web4-…

以“防方视角”观JS文件信息泄露

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 案例概述02 攻击路径03 防方思路 01 案例概述 这篇文章来自微信公众号“黑白之道”&#xff0c;记录的某师傅从js文件泄露接口信息&#xff0c;未授权获取大量敏感信息以及通过逻辑漏洞登录管理员账…

Vue中路由守卫的详细应用

作为一名web前端开发者&#xff0c;我们肯定经常使用Vue框架来构建我们的项目。而在Vue中&#xff0c;路由是非常重要的一部分&#xff0c;它能够实现页面的跳转和导航&#xff0c;提供更好的用户体验。然而&#xff0c;有时我们需要在路由跳转前或跳转后执行一些特定的逻辑&am…

go语言进阶篇——面向对象(一)

什么是面向对象 在我们设计代码时&#xff0c;比如写一个算法题或者写一个问题结局办法时&#xff0c;我们常常会使用面向过程的方式来书写代码&#xff0c;面向过程主要指的是以解决问题为中心&#xff0c;按照一步步具体的步骤来编写代码或者调用函数&#xff0c;他在问题规…

优化 IT 支出和消除浪费的 8 种主要方法

不懈追求最佳 IT 支出对于任何组织的长期可持续发展和成功都至关重要。在这个技术快速进步的时代&#xff0c;您必须做出明智的决策&#xff0c;消除浪费&#xff0c;同时最大限度地提高技术投资的价值。 从进行 IT 成本分析到采用敏捷预算和技术标准化&#xff0c;这些策略对…

双非本科准备秋招(19.1)—— Synchronized优化

轻量级锁 流程 一个对象虽然有多线程加锁&#xff0c;但是加锁时间是错开的&#xff0c;那么可以用轻量级锁优化。 语法还是synchronized&#xff0c;只是对使用者是透明的。 static final Object obj new Object(); public static void method1() {synchronized( obj ) {//…

(力扣)1314.矩阵区域和

给你一个 m x n 的矩阵 mat 和一个整数 k &#xff0c;请你返回一个矩阵 answer &#xff0c;其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和&#xff1a; i - k < r < i k, j - k < c < j k 且(r, c) 在矩阵内。 示例 1&#xff1a; 输入&a…

【Godot4.2】文件系统自定义控件 - FileSystemTree

FileSystemTree B站【Godot4.2】文件系统自定义节点 - FileSystemTree 概述 在Godot设计编辑器插件或应用程序时&#xff0c;可能需要涉及文件系统的显示&#xff0c;比如文件夹或文件的树形列表。 我们可以用Godot的Tree控件快速书写相应的功能&#xff0c;但是为了复用到…

Wireshark不显示Thrift协议

使用Wireshark对thrift协议进行抓包&#xff0c;但是只显示了传输层的tcp协议&#xff1a; "右键" -> "Decode As" 选择thrift的tcp端口 将“当前”修改为Thrift&#xff0c;然后点击“确定” 设置后&#xff0c;可以发现Wireshark里面显示的协议从Tcp变…

H12-821_74

74.在某路由器上查看LSP&#xff0c;看到如下结果&#xff1a; A.发送目标地址为3.3.3.3的数据包时&#xff0c;打上标签1026&#xff0c;然后发送。 B.发送目标地址为4.4.4.4的数据包时&#xff0c;不打标签直接发送。 C.当路由器收到标签为1024的数据包&#xff0c;将把标签…

波纹扩散效果

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>波纹扩散</title><style>body {disp…

『运维备忘录』之 Kubernetes(K8S) 常用命令速查

一、简介 kubernetes&#xff0c;简称K8s&#xff0c;是用8代替名字中间的8个字符“ubernete”而成的缩写&#xff0c;是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用。kubernetes是基于容器技术的分布式架构解决方案&#xff0c;具有完备的集群管理能力&a…

mysql入门到精通005-基础篇-约束

1、概述 1.1 概念 约束是作用于表中字段上的规则&#xff0c;用于限制储存在表中的数据。 1.2 目的 保证数据库中数据的正确性、有效性和完整性。 1.3 常见的约束分类 一旦谈到外键&#xff0c;则至少涉及2张表约束是作用于表中字段上的&#xff0c;可以在创建表/修改表的…

CTFshow web(命令执行29-36)

?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-encode/resourceflag.php #文件包含 ?cinclude%0a$_GET[cmd]?>&cmdphp://filter/readconvert.base64-encode/…