JAVAEE初阶相关内容第八弹--多线程(初阶)

本文目录

阻塞队列

阻塞队列是什么?

标准库中的阻塞队列

生产者消费者模型

阻塞队列的实现

普通队列实现:

入队列:

出队列:

完整代码:

 加阻塞

加锁

加阻塞


阻塞队列

队列:先进先出,实际上还有一些特殊的队列,不一定非得遵守先进先出。

例如:优先级队列。PriorityQueue

阻塞队列也是特殊的队列,虽然也是先进先出的,但是带有特殊的功能。

消息队列也是特殊的队列,相当于是在阻塞队列的基础上,加上个“消息的类型”按照制定的类别进行先进先出。

阻塞队列是什么?

阻塞队列是一种特殊的队列,也遵守“先进先出”的原则。

阻塞队列可以是一种线程安全的数据结构,并且具有以下的特征:

(1)当队列满时,继续入队列就会阻塞,直到有其他线程从队列中取走元素。

(2)当队列空的时候,继续出队列也会阻塞,直到有其他线程往队列里插入元素。

标准库中的阻塞队列

阻塞队列的一个典型的应用场景就是“生产者消费者模型”。

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。

生产者消费者彼此之间不直接通讯,而是通过阻塞队列来进行通讯,所以生产者生产完数据不需要等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列中取。

生产者消费者模型给我们带来了两个很重要的好处:

1.实现了发送方和接收方的解耦。(降低耦合的过程就叫解耦)

2.可以做到“削峰填谷”,保证了系统的稳定性。

代码实现要求:首先会使用标准库提供的阻塞队列。其次需要自己实现一个简单的阻塞队列。

Queue提供的方法有三个:

1.入队列 offer

2.出队列 poll

3.取队首元素 peek

阻塞队列主要是两个:[带有阻塞功能的]

1.入队列 put

2.出队列 take

阻塞队列代码:

public class ThreadD21 {public static void main(String[] args) throws InterruptedException {BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>();blockingQueue.put("hi");String s = blockingQueue.take();System.out.println(s);}
}

生产者消费者模型

public class ThreadD22 {public static void main(String[] args) {BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();//创建两个线程//消费者线程Thread customer = new Thread(() ->{while (true){try {Integer result = blockingQueue.take();System.out.println("消费元素" +result);} catch (InterruptedException e) {throw new RuntimeException(e);}}});customer.start();Thread producer = new Thread(() ->{int count = 0;while(true){try {blockingQueue.put(count);System.out.println("生产元素 " + count);count++;Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}}});producer.start();}
}

运行代码结果:

阻塞队列的实现

普通队列实现:

实现阻塞队列,首先要实现普通队列,构建一个类,名为MyBlockingQueue1,在这个类中写出入队列和出队列的两个操作。

首先定义四个变量。定义一个数组,数组的长度,队首标记和队尾标记。

   private int[] items= new int[1000];private int tail = 0;private int head = 0;private int size = 0;
入队列:

传值进入,进行条件判断

如果元素个数与数组的长度相同,这时队满,没空插入新元素,进行返回。

将想入队列的元素赋值给尾标记的位置,将尾标记向后加加指向后一个元素。

如果尾标记指向的位置大于或者等于数组的长度,则将尾标记置为0。

最后数组进行size++操作。

迷糊点:items.length与size的区别!一个是系统就给这个数组分配了这么多的存储空间,而size是实际上数组这里存储的长度。

还要注意tali++的位置!

//入队列操作public void put(int value){if(size == items.length){return;}items[tail] = value;tail ++;if(tail >= items.length ){tail = 0;}size++;}
出队列:

首先进行判断,假如队列为空,size等于0,则不能出队列,返回。

如果头标记的位置大于等于整个数组的长度,则需要将头标记位记为0.

进行修改,设置一个变量result,将头标记指向的元素存到result中,返回。

head标记为进行向后挪动,数组里真正的元素少1所以进行size--操作。

注意代码执行的位置!!

//出队列操作
public Integer take(){if(size == 0){return null;}int result =items[head];head++;if(head >= items.length){head = 0;}size--;return result;}
完整代码:

在主函数中需要注意的点:

拿出元素queue.take()

放入元素queue.put(value)

class MyBlockingQueue1{private int[] items= new int[1000];private int tail = 0;private int head = 0;private int size = 0;//入队列public void put(int value){if(size == items.length){return;}items[tail] = value;tail ++;if(tail >= items.length ){tail = 0;}size++;}//出队列public Integer take(){if(size == 0){return null;}int result =items[head];head++;if(head >= items.length){head = 0;}size--;return result;}
}
public class ThreadD23 {public static void main(String[] args) throws InterruptedException {MyBlockingQueue queue = new MyBlockingQueue();queue.put(1);queue.put(2);queue.put(3);queue.put(4);int result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);}
}

 加阻塞

需要注意的是,这里加阻塞功能就以为着程序是要在多线程条件下。要想实现阻塞功能,首先要保证需要实现线程安全。

加锁

首先为了保证线程安全,就需要将代码上锁,如图:

加阻塞

自己版本的阻塞队列最终版代码实现:

class MyBlockingQueue1{private int[] items= new int[1000];private int tail = 0;private int head = 0;private int size = 0;//入队列public void put(int value) throws InterruptedException {synchronized (this) {while(size == items.length){//return;this.wait();}items[tail] = value;tail ++;if(tail >= items.length ){tail = 0;}//这个notify唤醒的是take的waitthis.notify();size++;}}//出队列public Integer take() throws InterruptedException {int result = 0;synchronized (this) {while(size == 0){// return null;this.wait();}result =items[head];head++;if(head >= items.length){head = 0;}size--;//唤醒put中的wait;this.notify();}return result;}
}
public class ThreadD23 {public static void main(String[] args) throws InterruptedException {MyBlockingQueue queue = new MyBlockingQueue();queue.put(1);queue.put(2);queue.put(3);queue.put(4);int result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);result = queue.take();System.out.println("result = "+result);}
}

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

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

相关文章

量化:基于支持向量机的择时策略

文章目录 参考机器学习简介策略简介SVM简介整体流程收集数据准备数据建立模型训练模型测试模型调节参数 参考 Python机器学习算法与量化交易 利用机器学习模型&#xff0c;构建量化择时策略 机器学习简介 机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。…

请重新安装msvcp140.dll的修复方法,多种msvcp140.dll的处理方案

当你在电脑上安装或运行某些程序时出现了“缺少msvcp140.dll”或“msvcp140.dll丢失”会要求你“重新安装msvcp140.dll”等的错误提示&#xff0c;这意味着你的计算机缺少了一个重要的动态链接库文件。msvcp140.dll是微软Visual C Redistributable for Visual Studio 2015库的一…

硬件总线基础07:PCIe总线基础-事务层(2)

说在开头&#xff1a;关于哲学 在《东邪西毒》电影里欧阳锋说&#xff1a;“看来你的年纪也有四十出头了&#xff0c;这四十多年来&#xff0c;总有些事你是不愿再提&#xff0c;或是有些人不想再见&#xff0c;有的人曾经对不起你&#xff0c;也许你想过杀了他们&#xff0c;…

vue2中使用富文本编辑器tinyMCE全过程

第一步&#xff1a;安装TinyMCE $npm install tinymce5.10.0 -S $npm install tinymce/tinymce-vue3.0.1 -S 第二步&#xff1a;在node_modules中找到tinymce文件夹将内部文件移入pubilc/tinymce文件夹中在index.html文件中引入tinymce.min.js 注意&#xff1a;不把js文件放…

在 Arweave 中轻松管理文件:借助 4EVERLAND 完成 Web3 前端Path Manifests的终极指南

为什么使用Path Manifests&#xff1f; 当在 IPFS 上发布 NFT 时&#xff0c;图片和元数据会被上传到 IPFS 网络以获得一个根 CID&#xff0c;其形式如下&#xff1a; ipfs://bafybeic36ik6cngu37xbzmpytuvyo7z3lyeen44clkkxq5d263zj4nkzr4 通过使用这个根 CID&#xff0c;每…

运算放大器典型应用(二)

文章目录 十、采样保持电路十一、有源滤波电路二阶有源低通滤波器问题二阶截至频率如何算 十、采样保持电路 十一、有源滤波电路 给单片机供电R一般大于4.1Ω小于10Ω&#xff0c;太大会产生功耗 二阶有源低通滤波器问题 二阶截至频率如何算 通频带比较窄可以用这种&#xff0…

揭秘策划行业就业前景怎么样?

策划这个行业总的来说就是&#xff1a;门槛低&#xff0c;上限高&#xff01;&#xff01; 咱们一般说的策划也分很多类型&#xff0c;这里选取身边朋友做的最多的4种类型简单说说。 1、前端品牌策划&#xff0c;转型容易出路广 品牌策划以品牌思维为核心去分析公司的经营发…

计算机毕业设计 高校课程评价系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Revit SDK 介绍:AddSpaceAndZone 添加空间和分区

前言 这个例子介绍添加空间和分区。 内容 从 UI 界面看空间和分区。“分析”选项卡“空间和分区”面板&#xff1a; 创建空间 点击“Create Space”按钮&#xff0c;点“OK”&#xff0c;出现右边所示的6个空间。 核心逻辑&#xff1a; // SpaceManager::CreateSpaces(…

Redis的java客户端

在Redis官网中提供了各种语言的客户端&#xff0c;地址&#xff1a;https://redis.io/resources/clients/ redis的java客户端 https://redis.io/resources/clients/#java 1.jedis使用 引入依赖 <dependency><groupId>redis.clients</groupId><artifac…

类和对象(1)

文章目录 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符和封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化6.2结构体内存对齐规则 7.this指针7.2this指针的特性 封装&#xff08;补充&#xff09; 1.面向过程和面向对象初步认识 C面向对象但不纯面向…

时间和空间复杂度

目录 一、如何衡量一个算法的好坏 二、算法效率 三、时间复杂度 3.1 时间复杂度概念 3.2 大O的渐进表示法 3.3 推导大O阶方法 3.4 常见时间复杂度计算 3.5 空间复杂度 一、如何衡量一个算法的好坏 以下是求斐波那契数列的算法&#xff0c;这个算法是好还是不好呢&#xff1f…

ARM Linux DIY(八)USB 调试

前言 V3s 带有一个 USB 接口&#xff0c;将其设置为 HOST 或 OTG 模式&#xff0c;这样可以用来接入键盘、鼠标等 USB 外设。 USB 简介 USB 有两种设备&#xff1a;HOST 和 USB 功能设备。 在 USB2.0 中又引入了一个新的概念 OTG&#xff0c;即设备角色可以动态切换。 切换方…

ctfhub ssrf(3关)

文章目录 内网访问伪协议读取文件扫描端口 内网访问 根据该题目&#xff0c;是让我们访问127.0.0.1/falg.php&#xff0c;访问给出的链接后用bp抓包&#xff0c;修改URL&#xff0c;发送后得到flag&#xff1a; 伪协议读取文件 这题的让我们用伪协议&#xff0c;而网站的目录…

Java 基本类型和包装类

Java 是基于对象的&#xff0c;所以我们都需要以对象的想法来进行思维。 但 Java 又提供了 8 个基本类型&#xff0c;这 8 个基本类型基本上都和数字有关&#xff0c;是直接可以使用的类型。 基本类型大小包装器类型boolean/Booleanchar16bitCharacterbyte8bitByteshort16bitS…

C#下使用IronPython来实现热更新

问题 之前我们学习过Roslyn&#xff0c;他可以动态编译代码并运行&#xff0c;然后通过ALC加载即插即用&#xff0c;但是遇到一些问题感觉无法解决&#xff0c;我编写一个类A在ALC中&#xff0c;另外一个类B要实例化这个A&#xff0c;我想让他们都能灵活卸载&#xff0c;但是如…

wireshark通常无法抓取交换机所有端口报文

Wireshark 是一种网络分析工具&#xff0c;它通常在计算机的网络接口上进行数据包捕获和分析。然而&#xff0c;Wireshark 默认情况下无法直接捕获交换机所有端口的报文。 交换机是一种网络设备&#xff0c;它在局域网内转发数据包&#xff0c;根据目的MAC地址将数据包仅发送到…

使用mybatis批量插入数据

最近在做项目的时候&#xff0c;有些明细数据&#xff0c;一条一条的插入太费资源和时间&#xff0c;所以得需要批量插入&#xff0c;今晚闲来无事写个小demo。 新建工程 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis…

基于腾讯文档进行应届生个人求职记录

1. 新建一个腾讯文档 电脑登录QQ&#xff0c;点击“腾讯文档”功能键。 2. 可以选择下载客户端&#xff0c;也可以直接进入网页版。&#xff08;本人使用网页版&#xff09; 3. 点击新建&#xff0c;选择在线表格。 4. 编辑表名&#xff0c;表内容。 5. 设置文档权限&#xf…

性能测试工具LoadRunner —— 性能测试流程及结果分析

性能测试目的 1 什么是性能测试? 性能测试是通过性能的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。 负载测试和压力测试都属于性能测试&#xff0c;两者可以结合进行。通过负载测试&#xff0c;确定在各种工作负载下系统的性能&#xff0…