Java:双缓冲队列

《程序员》:双缓冲队列就是冲着同步/互斥的开销来的。我们知道,在多个线程并发访问同一个资源的时候,需要特别注意线程的同步问题。稍稍不注意,哦活,程序结果不正确了。最经典的就是“银行取钱”的例子,想想,都跟现金挂上钩了,看来这真不容忽视。

今天我们要谈的不是如何去给资源加锁解锁来解决同步问题,今天的重点在于,如何将线程同步的开销降低到我们力所能及的程度。如果你觉得,你可以通过增加硬件资源来弥补程序开销,那么,你将不可能成为一个优秀的程序员。

进入正题,先引入一个例子,两个实体:一个是玩具工厂,它的工作就是不停地生产玩具;另外一个实体就是小孩,它的工作就是不停地从工厂拿玩具。小孩不可能直接到工厂去“拿”玩具吧?呵呵,妈妈是绝对不会放心的。所以,我们有一个“搬运工”,搬运工自然要具备“存放”的功能,不然他怎么将玩具带给小孩呢,是吧。所以,我们先将搬运工定义为一个List,用来存放工厂生产出来的玩具。

玩具类,定义一个玩具实体 >> 

@Data
public class Toy {private String name;}

生产玩具的玩具工厂,相当于生产者 >> 

public class Factory extends Thread {public void run() {while (true) {Toy toy = new Toy();toy.setName("玩具");synchronized (Tools.lp) {if (Tools.lp.size() >= 2000) {try {Tools.lp.wait();} catch (Exception e) {// TODO: handle exception}}Tools.lp.add(t);// System.out.println("put one");}}}
}

小孩取玩具,相当于消费者 >> 

public class Kid extends Thread {long time1 = System.currentTimeMillis();int count = 0;public void run() {while (true) {synchronized (Tools.lt) {if (Tools.lt.size() != 0){Tools.lt.remove(0);count++;} }if (count == 100000) {System.out.println("time:" + (System.currentTimeMillis() - time1));System.exit(0);}}}
}

双缓冲队列,里面有两个List >> 

public class DoubleBufferList {private List<Object> lp;private List<Object> lt;private int gap;public DoubleBufferList(List lp, List lt, int gap) {this.lp= lp;this.lt= lt;this.gap = gap;}public void check() {Runnable runner = new Runnable() {public void run() {while (true) {if (lt.size() == 0) {synchronized (lt) {synchronized (lp) {lt.addAll(lp);lp.notifyAll();}lp.clear();}}}}};Thread thread = new Thread(runner);thread.start();}
}

运行的主线程类 >> 

public class BaseTest {public static void main(String[] args) {Factory f = new Factory();f.start();Kid k = new Kid();k.start();new DoubleBufferList(Tools.lp, Tools.lt, 1).check();}}

运行结果:比用一个List的生产者消费者模型快很多.大家可以测试下运行速度根据自己的实际情况进行使用

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

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

相关文章

七麦数据js逆向(补环境版)

本文目标地址如下&#xff0c;使用base64解码获得 aHR0cHM6Ly93d3cucWltYWkuY24vcmFuay9tYXJrZXRSYW5rL21hcmtldC82L2NhdGVnb3J5LzUvY29sbGVjdGlvbi9hbGwvZGF0ZS8yMDI0LTAxLTEy 本文逆向破解分为扣代码版和补环境版&#xff0c;扣代码版请看专栏另一篇文章 废话不多说了&#…

Cesium笔记 viewer控件隐藏

Cesium初始化后&#xff0c;场景中会有时间轴&#xff0c;动画&#xff0c;home等控件显示&#xff0c;需要将这些控件隐藏&#xff0c;如下&#xff1a; init() {let viewer new Cesium.Viewer("cesiumContainer", {fullscreenButton: false, // 隐藏界面右下角全…

“具身智能”浪潮中,达闼机器人的商业化“奇点”已然到来?

当前&#xff0c;人形机器人产业正在快速发展&#xff0c;而2023年必将会是载入史册的一年。 具体来看&#xff0c;2023年&#xff0c;AI技术大爆发&#xff0c;可在语言、视觉、运动控制、降低研发成本等多方面赋能人形机器人产业发展。与此同时&#xff0c;特斯拉、波士顿动…

【C++】C++11中的常见语法(下)

C11 一、可变参数模板1. 递归函数方式展开参数包2. 逗号表达式展开参数包3. STL容器中的 empalce 相关接口函数 二、lambda 表达式1. C98 中的一个例子2. 使用 lambda 表达式3. lambda 表达式语法&#xff08;1&#xff09;lambda 表达式各部分说明&#xff08;2&#xff09;捕…

1-Docker-基础

本文内容多处参考黑马程序员的公开资料&#xff0c;仅用来个人梳理&#xff0c;原资料地址&#xff1a;https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec Docker介绍 为什么要用Docker&#xff1f; 以Mysql安装为例&#xff0c;想要在Linux系统上安装Mysql&…

Mysql适配国产化数据库人大金仓冲突记录

1、mysql中查询中如果使用双引号&#xff0c;在人大金仓数据库中不支持&#xff0c;需改为单引号 例如&#xff1a; select 字段A&#xff0c;字段B&#xff0c;字段C from tableA where 字段A "1" 改为&#xff1a; select 字段A&#xff0c;字段B&#xff0c;字段…

c++简单做一个文件变长储存(自己封装字符串类)

c简单做一个文件变长储存 前言源码所有类头文件 .hClassStuMyStrcFile 所有文件的实现源码.cppclassstuMystrcFile 前言 用户信息写到文件是变长方式&#xff1b; 从文件上读取到内存&#xff0c;也是变长方式 用到了三个类&#xff1b; ** 用户信息类 ClassStu ** 自封装字符…

Vue+Element UI+Echarts

Vue文档 Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) 一个简单的基于vue.js的无缝滚动 vue-seamless-scroll (chenxuan0000.github.io) Element&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 Element - 网站快速成型工具 ECharts …

【C】volatile 关键字

目录 volatile1&#xff09;基本概念2&#xff09;用途&#xff1a;禁止编译器优化3&#xff09;总结 volatile 1&#xff09;基本概念 const是C语言的一个关键字。 const用于告诉编译器相应的变量可能会在程序的控制之外被修改&#xff0c;因此编译器不应该对其进行优化。 …

2024年AMC8往年真题练一练和答案详解(6),还有全真模拟题

今天是1月13日&#xff0c;2024年AMC8正式比赛已经倒计时了&#xff0c;昨天AMC主办方给所有参赛选手发了短信通知&#xff0c;关于模拟竞赛的操作方式和实际比赛的要求指南&#xff0c;大家一定要认真阅读&#xff0c;严格按指南操作&#xff0c;六分成长也会详细为大家解读和…

Stable Diffusion的 webui 如何在Windows上使用 AMD GPU显卡?

根据Stable Diffusion官方说明 webui 是不支持AMD GPU显卡的&#xff0c;所以在国内如果想省点事情要玩Stable Diffusion (SD) 推荐用黄教主的英伟达显卡NVIDIA GPU&#xff0c;可以省心不少。 AMD显卡得用 webui-directml&#xff0c;这是另外的包&#xff0c;按官方的说明实…

编程竞赛-消息存取

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; GitHub - September26/java-algorithms: 算法题汇总&#xff0c;包含牛客&#xff0c;leetCode&#xff0c;lintCode等网站题目的解法和代码&#xff0c;以及完整的mode类&#…

LinkedList和ArrayList

LinkedList和ArrayList都是Java中的List接口的实现 内部数据结构&#xff1a; ArrayList是基于动态数组实现的&#xff0c;它支持快速的随机访问&#xff0c;也就是说&#xff0c;获取指定索引位置的元素非常快&#xff0c;时间复杂度为O(1)。 LinkedList是基于双向链表…

input框不可编辑的方法

input框不可编辑的方法 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将探讨一个在前端开发中常见的问题——“input框不可编辑的方法”。无论…

在 Nvidia Docker 容器编译构建显存优化加速组件 xFormers

本篇文章&#xff0c;聊聊如何在新版本 PyTorch 和 CUDA 容器环境中完成 xFormers 的编译构建。 让你的模型应用能够跑的更快。 写在前面 xFormers 是 FaceBook Research &#xff08;Meta&#xff09;开源的使用率非常高的 Transformers 加速选型&#xff0c;当我们使用大模…

掌握 gRPC 和 RPC 的关键区别

一、远程过程调用协议简介 1、RPC 的本质 首先&#xff0c;我们探讨一下什么是 RPC。RPC&#xff0c;缩写为 Remote Procedure Call Protocol&#xff0c;直译来看就是远程过程调用协议。 讲得通俗一些&#xff1a; RPC 是一种通信机制RPC 实现了客户端/服务器通信模型 官…

教程-右键用vscode(新窗口)打开文件或目录

通过本文可以提高效率&#xff0c;用起来更爽更高效。 本文实现了&#xff08;windows系统&#xff09;&#xff1a; 右键-用vscode(当前窗口)打开文件或目录右键-用vscode-新窗口打开文件或目录 注意&#xff1a; 下面的安装路径要更改为您实际的路径 具体配置步骤&#x…

TS报错:类型‘object‘上不存在属性‘product_id’

问题&#xff1a; TS报错&#xff1a;类型object上不存在属性product_id。 解决办法&#xff1a; 下面是一个示例代码&#xff0c;演示了如何使用条件语句来安全地从对象中获取属性值&#xff1a; // 使用条件语句进行安全访问 if (dataSource.value.length > 0 &&…

边缘计算:连接实时数据的力量与未来发展之路

边缘计算是一种分布式计算范式&#xff0c;它旨在将数据处理、存储和应用服务带到数据源的近端&#xff0c;即网络的“边缘”。在边缘计算模型中&#xff0c;算力和存储资源距离末端用户或数据源更近&#xff0c;这减少了数据在网络中传输的距离&#xff0c;从而降低延迟&#…

imgaug库指南(19):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…