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.rhkb.cn/news/130886.html

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

相关文章

Redis缓存魔法:如何轻松提升你的应用性能

Redis&#xff0c;作为一个开源的、内存中的数据结构存储系统&#xff0c;已经成为了许多开发者和企业的首选工具。无论是作为数据库、缓存还是消息代理&#xff0c;Redis都展现出了其强大的性能和灵活性。在本文中&#xff0c;我们将深入探讨Redis的魅力&#xff0c;以及如何有…

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

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

无涯教程-JavaScript - OCT2BIN函数

描述 OCT2BIN函数将八进制数转换为二进制数。 语法 OCT2BIN (number, [places])争论 Argument描述Required/OptionalNumber 您要转换的八进制数。 数字不能超过10个字符。数字的最高有效位是符号位。其余的29位是幅度位。 负数使用二进制补码表示。 RequiredPlaces 要使用的…

【C语言】字符串函数

文章目录 前言1.strcat2.strncpy3.strncat4.strncmp5.strstr6.strtok7.strerror8.strcat的模拟实现9.strstr的模拟实现 总结 添加链接描述 前言 大家好呀&#xff0c;今天给大家分享一下字符函数和字符串函数C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没…

随机密码生成器(Python)

随机密码生成器 想要生成一个随机密码&#xff0c;需要考虑下面两点&#xff1a; 1.字符集合 2.密码的位数 下面代码中引用了string模块和random模块&#xff0c;string.printable是string中的可打印字符&#xff0c;用strip函数首尾去掉空格&#xff1b;random模块用来取字符&…

C# wpf 实现桌面放大镜

文章目录 前言一、如何实现&#xff1f;1、制作无边框窗口2、Viewbox放大3、截屏显示&#xff08;1&#xff09;、截屏&#xff08;2&#xff09;、转BitmapSource&#xff08;3&#xff09;、显示 4、定时截屏 二、完整代码三、效果预览总结 前言 做桌面截屏功能时需要放大镜…

品牌策划经理工作内容|工作职责|品牌策划经理做什么?

一位美国作家曾说过“品牌是一系列期望、记忆、故事和关系&#xff0c;他们共同构成了消费者最终原则一个产品或者服务的原因。” 所以&#xff0c;品牌经理这个岗位主要是创造感知价值主张&#xff0c;激发消费者购买这个品牌后带来的感知价值&#xff0c;这种回报的本质相对…

C语言实现三子棋游戏(详解)

目录 引言&#xff1a; 1.游戏规则&#xff1a; 2.实现步骤&#xff1a; 2.1实现菜单&#xff1a; 2.2创建棋盘并初始化&#xff1a; 2.3绘制棋盘&#xff1a; 2.4玩家落子&#xff1a; 2.5电脑落子&#xff1a; 2.6判断胜负&#xff1a; 3.源码&#xff1a; 结语&…

论文阅读 (100):Simple Black-box Adversarial Attacks (2019ICML)

文章目录 1 概述1.1 要点1.2 代码1.3 引用 2 背景2.1 目标与非目标攻击2.2 最小化损失2.3 白盒威胁模型2.4 黑盒威胁模型 3 简单黑盒攻击3.1 算法3.2 Cartesian基3.3 离散余弦基3.4 一般基3.5 学习率 ϵ \epsilon ϵ3.6 预算 1 概述 1.1 要点 题目&#xff1a;简单黑盒对抗攻…

力扣刷题-移除指定值的链表元素

力扣203移除元素 题目来源&#xff1a; 力扣203 题目描述&#xff1a; 非常简单的一道题&#xff0c;主要强调两点 链表删除要记录删除位置的前驱节点 头节点没有前驱 因此直接headhead.next为了保持与后两种一致&#xff0c;加上虚拟节点&#xff0c;下一节点指向头节点 /***…

【Linux-Day10-信号量,共享内存,消息队列】

信号量 信号量描述 信号量是一个特殊的变量&#xff0c;一般取正数值。它的值代表允许访问的资源数目&#xff0c;获取资源 时&#xff0c;需要对信号量的值进行原子减一&#xff0c;该操作被称为 P 操作。 当信号量值为 0 时&#xff0c;代表没有资源可用&#xff0c;P 操作…

企业架构LNMP学习笔记27

Keepalived的配置补充&#xff1a; 脑裂&#xff08;裂脑&#xff09;&#xff1a;vip出现在了多台机器上。网络不通畅&#xff0c;禁用了数据包&#xff0c;主备服务器没法通讯&#xff0c;造成备服务器认为主服务器不可用&#xff0c;绑定VIP&#xff0c;主服务器VIP不会释放…

【设计模式】三、概述分类+单例模式

文章目录 概述设计模式类型 单例模式饿汉式&#xff08;静态常量&#xff09;饿汉式&#xff08;静态代码块&#xff09;懒汉式(线程不安全)懒汉式(线程安全&#xff0c;同步方法)懒汉式(线程安全&#xff0c;同步代码块)双重检查静态内部类枚举单例模式在 JDK 应用的源码分析 …

[N0wayback 2023春节红包题] happyGame python反编译

这个反编译的比较深 一&#xff0c;从附件的图标看是python打包的exe文件&#xff0c;先用pyinstxtractor.py 解包 生成的文件在main.exe_extracted目录下&#xff0c;在这里边找到main 二&#xff0c;把main改名为pyc然后加上头 这个头从包里找一个带头的pyc文件&#xff…

做题(1)

1.fileinclude 打开 发现提示flag在flag.php里边 查看页面源代码 $lan $_COOKIE[language]; 这句话是关键 变量lan是用cookie传参的 include("english.php"); 这句话表明了文件包含 include函数用php伪协议 filer绕过 include($lan.".php"); 这句话…

深入实现 MyBatis 底层机制的任务阶段4 - 开发 Mapper 接口和 Mapper.xml

&#x1f600;前言 在我们的自定义 MyBatis 底层机制实现过程中&#xff0c;我们已经深入研究了多个任务阶段&#xff0c;包括配置文件的读取、数据库连接的建立、执行器的编写&#xff0c;以及 SqlSession 的封装。每个任务阶段都为我们揭示了 MyBatis 内部工作原理的一部分&a…

【算法基础】时间复杂度和空间复杂度

目录 1 算法的评价 2 算法复杂度 2.1 时间复杂度&#xff08;Time Complexity&#xff09; 2.1.1 如何计算时间复杂度&#xff1a; 2.1.2 常见的时间复杂度类别与示例 2.2 空间复杂度 2.2.1 如何计算空间复杂度 2.2.2 常见的空间复杂度与示例 3 时间复杂度和空间复杂度…

Linux——环境变量

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——环境变量 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;环境变量(environment variables)一般是指在操作系统中用来指定操作…

linux下检测CPU性能的mpstat命令安装与用法

1、安装命令 $ sudo apt-get install sysstat sysstat安装包还包括了检测设备其它状态的命令&#xff0c;查看命令如下&#xff1a; 2、检测CPU命令语法 $ mpstat --h //查看mpstat的语法 Usage: mpstat [ options ] [ <interval> [ <count> ] ] Options are: …

期货基础知识

一、期货是什么&#xff1f;  期货是与现货相对应&#xff0c;并由现货衍生而来。期货通常指期货合约&#xff0c;期货与现货完全不同&#xff0c;现货是实实在在可以交易的货&#xff08;商品&#xff09;&#xff0c;期货主要不是货&#xff0c;而是以某种大众产品如棉花、大…