网易一面,痛失30K:为啥用阻塞队列,list不行吗?

2023-10-26

9c4ffd1ec40bf01d25d11c26ae12c02a.jpeg

程序员的成长之路

互联网/程序员/技术/资料共享 

关注

阅读本文大概需要 5.5 分钟。

来自:技术自由圈

本文目录

- 说在前面

- 1、什么是阻塞队列?

- 2、主要并发队列关系图

- 3、阻塞队列和 List、Set 的区别是什么?

- 4、阻塞队列和普通Queue 队列的区别是什么?

- 5、阻塞队列的作用

- 6、阻塞队列的功能

- 7、阻塞队列的核心方法

  - 7.1 take 方法

  - 7.2 put 方法

  - 7.3 是否有界(容量有多大)

- 尼恩提示

- 说在后面

1、什么是阻塞队列?

阻塞队列是一种队列,阻塞队列是一种特殊的队列。

阻塞队列是一种可以在多线程环境下使用,并且支持阻塞等待的队列。

f8bb766a5d2c90ac833694a65cedebaa.png

线程 1 往阻塞队列中添加元素,当阻塞队列是满的,线程 1就会阻塞,直到队列不满

线程 2 从阻塞队列中移除元素,当阻塞队列是空的,线程 2 会阻塞,直到队列不空;

2、主要并发队列关系图

11ed7998532894677b18af18a0f56e40.png

上图展示了 Queue 最主要的实现类,可以看出 Java 提供的线程安全的队列(也称为并发队列)分为阻塞队列和非阻塞队列两大类。

BlockingQueue 下面有 6 种最主要的阻塞队列实现,分别是

  • ArrayBlockingQueue

  • LinkedBlockingQueue

  • SynchronousQueue

  • DelayQueue

  • PriorityBlockingQueue

  • LinkedTransferQueue

非阻塞并发队列的典型例子是 ConcurrentLinkedQueue,这个类不会让线程阻塞,利用 CAS 保证了线程安全。

我们可以根据需要自由选取阻塞队列或者非阻塞队列来满足业务需求。

还有一个和 Queue 关系紧密的 Deque 接口,它继承了 Queue,如代码所示:

public interface Deque<E> extends Queue<E> {//...}

Deque 的意思是双端队列,音标是 [dek],是 double-ended-queue 的缩写,它从头和尾都能添加和删除元素;而普通的 Queue 只能从一端进入,另一端出去。这是 Deque 和 Queue 的不同之处,Deque 其他方面的性质都和 Queue 类似。

3、阻塞队列和 List、Set 的区别是什么?

阻塞队列和 List、Set 一样都继承自 Collection。

阻塞队列它和 List 的区别在于,List 可以在任意位置添加和删除元素。

而阻塞队列属于 Queue   队列的一种,Queue  只有两个操作:

  • 把元素添加到队列末尾;

  • 从队列头部取出元素。

超市的收银台就是一个队列:

c3ef0b41ad1a6654538274903f612a14.jpeg

我们常用的 LinkedList 就可以当队列使用,实现了 Dequeue 接口,还有 ConcurrentLinkedQueue,他们都属于非阻塞队列。

4、阻塞队列和普通Queue  队列的区别是什么?

阻塞队列和一般的队列的区别就在于:

  • 多线程环境支持,多个线程可以安全的访问队列

  • 支持生产和消费等待,多个线程之间互相配合,在某些情况下会挂起线程,一旦条件满足,被挂起的线程又会自动被唤醒

  • 当阻塞队列是空的,消费线程会阻塞,从队列中获取元素的操作将会被阻塞,直到队列不空

  • 当阻塞队列是满的,生产线程就会阻塞,往队列里添加元素的操作将会被阻塞,直到队列不满

5、阻塞队列的作用

阻塞队列,也就是 BlockingQueue,它是一个接口,如代码所示:

public interface BlockingQueue<E> extends Queue<E>{...}

BlockingQueue 继承了 Queue 接口,是队列的一种。

Queue 和 BlockingQueue 都是在 Java 5 中加入的。

BlockingQueue 是线程安全的,在很多场景下都可以利用线程安全的队列来优雅地解决业务自身的线程安全问题。

比如说,使用生产者/消费者模式的时候,生产者只需要往队列里添加元素,而消费者只需要从队列里取出它们就可以了,如图所示:

a9eef525ba7b3ce548825cf1af90bae2.png

在图中,左侧有三个生产者线程,它会把生产出来的结果放到中间的阻塞队列中,而右侧的三个消费者也会从阻塞队列中取出它所需要的内容并进行处理。因为阻塞队列是线程安全的,所以生产者和消费者都可以是多线程的,不会发生线程安全问题。

既然队列本身是线程安全的,队列可以安全地从一个线程向另外一个线程传递数据,所以生产者/消费者直接使用线程安全的队列就可以,而不需要自己去考虑更多的线程安全问题。这也就意味着,考虑锁等线程安全问题的重任从“你”转移到了“队列”上,降低了开发的难度和工作量。

同时,队列还能起到一个隔离的作用

比如说开发一个银行转账的程序,那么生产者线程不需要关心具体的转账逻辑,只需要把转账任务,如账户和金额等信息放到队列中就可以,而不需要去关心银行这个类如何实现具体的转账业务。而作为银行这个类来讲,它会去从队列里取出来将要执行的具体的任务,再去通过自己的各种方法来完成本次转账。

这样就实现了具体任务与执行任务类之间的解耦,任务被放在了阻塞队列中,而负责放任务的线程是无法直接访问到银行具体实现转账操作的对象的,实现了隔离,提高了安全性。

6、阻塞队列的功能

阻塞队列区别于其他类型的队列的最主要的特点就是“阻塞”这两个字,

所以下面重点介绍阻塞功能:阻塞功能使得生产者和消费者两端的能力得以平衡,当有任何一端速度过快时,阻塞队列便会把过快的速度给降下来。

7、阻塞队列的核心方法

方法类型 抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e,time,unit)
移除 remove() poll() take() poll(time,unit)
检查 element peek 不可用 不可用
  1. 抛异常的方法  就是在插入满了之后,会报一个异常,remove一样,element是检查队头的元素或者是否为空。

  2. 特殊值的方法是在插入满之后返回值变成了false而不是一个异常,取出失败的时候返回null。

  3. 阻塞方法是在插入满之后把这个方法阻塞,一直等待队列空出来一个之后再进行加入,会出现一直等待,也可能出现饥饿现象。

  4. 超时方法的话,当阻塞队列满时,队列会阻塞生产者线程一定时间,超过限时后生产者线程会退出。

实现阻塞最重要的两个方法是 take 方法和 put 方法。

7.1 take 方法

take 方法的功能是获取并移除队列的头结点,通常在队列里有数据的时候是可以正常移除的。

可是一旦执行 take 方法的时候,队列里无数据,则阻塞,直到队列里有数据。

一旦队列里有数据了,就会立刻解除阻塞状态,并且取到数据。

过程如图所示:

ec2110bf4152214f1b7951a41b259960.png

7.2 put 方法

put 方法插入元素时,如果队列没有满,那就和普通的插入一样是正常的插入,但是如果队列已满,那么就无法继续插入,则阻塞,直到队列里有了空闲空间。

如果后续队列有了空闲空间,比如消费者消费了一个元素,那么此时队列就会解除阻塞状态,并把需要添加的数据添加到队列中。

put  过程如图所示:

3bb0db747cfc2696b8f081ed899e362e.png

以上过程中的阻塞和解除阻塞,都是 BlockingQueue 完成的,不需要我们自己处理。

7.3 是否有界(容量有多大)

此外,阻塞队列还有一个非常重要的属性,那就是容量的大小,分为有界和无界两种。

  • 有的阻塞队列是无界的,无界队列意味着里面可以容纳非常多的元素,例如 LinkedBlockingQueue 的上限是 Integer.MAX_VALUE,约为 2 的 31 次方,是非常大的一个数,可以近似认为是无限容量,因为几乎无法把这个容量装满。

  • 但是有的阻塞队列是有界的,例如 ArrayBlockingQueue 如果容量满了,也不会扩容,所以一旦满了就无法再往里放数据了。

尼恩提示

更多的 JUC 高并发知识,请参见《Java 高并发核心编程 卷2 加强版》

说在后面

问题回答到这里,已经20分钟过去了,

既然  对阻塞队列 表达得那么娴熟,一定是遇到过很多的高并发场景,解决很多高并发问题,那么一定是技术大佬、技术高手,面试官已经爱到 “不能自已、口水直流” 啦。

offer,当然也就来了。

<END>

推荐阅读:

员工将密码设为“123456”,导致AMD被盗450GB数据

不好意思,list.contain 去重该换换了!

互联网初中高级大厂面试题(9个G)
内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
⬇戳阅读原文领取!                                  朕已阅
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网易一面,痛失30K:为啥用阻塞队列,list不行吗? 的相关文章

  • QT快速操作Excel的实现介绍及操作类封装

    QT中操作Excel还是比较简单的 Qt提供了QAxObject 包装COM组件的类 通过COM通过COM操作使用QAxObject类 使用此类 需要在pro文件中添加 QT axcontainer 基本流程介绍 QAxObject QAx
  • Linux系统:OpenSSH7.4p升级到9.0p

    目录 一 理论 1 ssh 2 OpenSSH 二 实验 1 OpenSSH升级 三 问题 1 远程SSH服务器拒绝X11转发请求 2 sshd服务重启报错 四 总结 一 理论 1 ssh 1 概念 ssh 是协议 基于22端口的安全协议
  • CB使用TINYXML类库进行XML操作

    由于看到网上对C 下的xml类库中tinyxml的评价比较好 因此 在最近的一个项目里上手使用了一下 发现该类对XML操作的封装的确不错 首先贴上要操作的XML内容
  • 解决每次挂起VM虚拟机后,docker容器无法访问的问题

    最近在学习docker 因为下班之后时间不多 每天也就学习一两个小时 期间遇到一个问题 就是每次挂起虚拟机后 第二天再次继续运行虚拟机 发现运行中的docker容器就无法访问了 必须重启docker才能重写访问 这样就很麻烦 于是在中文互联
  • 做公益的飞秋(FeiQ)程序代码

    丁磊是一个喜欢做公益的 飞秋 FeiQ 程序代码ceo 所以在2005年以个人名义向陶瓷红十字会 不知那时郭小姐是否已在红十字会任职 总会捐了当时国内最大的一笔个人捐款 用一百二十万美元帮助海啸受灾地区民众重建家园 所以即使今天很多互联网上
  • 呕心沥血!!总结2021前端必备面试题

    面试题 1 用递归算法实现 数组长度为5且元素的随机数在2 32间不重复 递归就是函数在内部自己调自己 1 这是一道大题目 把考点拆成了4个小项 需要候选人用递归算法实现 a 生成一个长度为5的空数组arr b 生成一个 2 32 之间的随
  • HTTP 特殊字段讲解, 断点续传讲解

    1 怎么判断http服务器是否支持断点续传 在服务器的响应中查找是否含有字段 Accept Ranges bytes 2 if match 服务端有个ETag 实体标记 的字段 与特定资源关联的确定值 当资源更新后Etag也会随之更新 所以
  • SQLMap使用教程:从入门到入狱详细指南

    项目地址 GitHub sqlmapproject sqlmap Automatic SQL injection and database takeover tool SQLMap支持市面上常见的数据库 支持MySQL Oracle Pos
  • 网络营销中的博客营销有什么价值?对于博客营销我们应该注意哪些问题?

    博客营销有什么价值 应该注意什么 博客营销的正向效应作为一种现代 新兴的互联网营销手段 博客营销具有着传统营销方式所不可比拟的价值 主要体现在其正向的外部性方面 第一 由于网络资源的共享性和交互性 博客营销有利于企业全面降低营销费用和经营成
  • 最全防雷器电路及保护电路解析

    一 交流电源防雷器 一 单相并联式防雷器 电路一 最简单的电路 说明 1 优点 电路简单 采用复合对称电路 共模 差模全保护 L N 可以随便接 缺点 压敏电阻RV1 短路失效后易引起火灾 最好在每个压敏电阻上串联一个工频保险丝以防压敏电阻
  • 虚拟linux系统首次登入,第一次在虚拟机启动我们的Linux系统

    在上一篇中 我们学习了如何在本地环境搭建自己的Linux学习环境 从今天开始 正式进入我们的Linux学习之旅 今天我们尝试第一次启动Linux系统 为保证虚拟机的流畅运行 建议将分辨率设置为 800x600 1 第一次启动Linux之后
  • SSD HDD RAM ROM NAND NOR Flash 等存储介质概念整理

    原文地址 http xyzhongly blog 163 com blog static 2820488820101022302695 fromdm fromSearch isFromSearchEngine yes 寄存器 寄存器是中央处
  • C# 发展史

    C 开发的进化史 今天开始呢 我会跟大家一起学习C 我会由浅入深从基础来教大家 给大家推荐一本个人认为最为适合C 入门的书 C 本质论 这本书写的确实不错 如果有兴趣的话可以买来看一看 在期刊期间我也会发一些关于有趣的小案例 努力让大家学到
  • 区块链应用的开发

    经过前面两篇文章 适合小白 区块链之我用可视化的方式部署Webase 区块链之我用可视化Webase开发智能合约 的洗礼 相信大家都对区块链这块多少有点了解了 在本章节小编将带大家演示一下区块链应用的开发 首先需要导出刚才编译部署的智能合约
  • 毕设(一):正则化极限学习机(RELM)、在线学习的极限学习机(OS-ELM)、带遗忘机制的在线学习极限学习机(FOS-ELM)

    前言 终于要毕业了 毕业设计也做完了 我的毕设是 极限学习机和强化学习在单一资产交易中的应用 本质上用以极限学习机为值函数逼近器的一类强化学习算法去对一个资产进行交易 既然毕设也做完了 大学生涯也要结束了 那在去工作之前将毕设的东西好好总结
  • 线性回归(Linear Regression)

    线性回归 Linear Regression 一 假设函数 h x
  • Linux 强行终止

    kill 9 pid pid是进程号 9 代表的是数字 INT 2 这个就是你在bash下面用Ctrl C 来结束一个程序时 bash会向进程发送这个信号 默认的 进程收到这个程序会结束 你可以用 kill INT pid 来发这个信号 Q
  • ORA-28547 连接服务器失败

    1 找到Oracle安装路径 找到Oracle安装路径 app product 11 2 0 dbhome 1 NETWORK ADMIN listener ora 2 在listener ora文件中找到 PROGRAM extproc
  • OpenAI使用条款、使用策略和支持的地区汇总:必读指南,避免OpenAI API被封禁

    最近 一些群友反馈他们的OpenAI API被限制 其中包括试用金用户以及绑定了信用卡的用户 当他们调用API时 会收到以下报错信息 Your access was terminated due to violation of our po
  • 第一章:认识Scratch 第一课 什么是编程,什么是计算机语言?

    程序员的高薪已经成为一个公开的秘密 北上广的一个普通的刚毕业的程序员 怎么说也要万元的起薪 工作几年之后 说起来月薪都是几万 那些高级的资深程序员甚至于达到了年薪百万的待遇 程序员的工作就是编程 那么到底什么是编程呢 关注公众号 少儿编程S

随机推荐

  • python3.6安装包下载_下载 - CPython v3.8.5 官方安装包,离线安装程序,绿色便携版

    CPython v3 8 5 官方安装包 for Digitser 基于 C 语言的 Python 实现 系统 Microsoft Windows Vista 7 8 10 x86 amd64 CPython2 7 原定于 2020 年 0
  • android cmd命令行删除文件夹,文件

    android cmd命令行删除文件夹 文件 adb root adb remount adb shell su cd system sd data 进入系统内指定文件夹 ls 列表显示当前文件夹内容 rm r xxx 删除名字为xxx的文
  • Angular Tracy 小笔记 数据绑定,指令

    数据绑定 数据绑定的本质 就是我们的通讯操作 左边的业务逻辑 ts 想传递数据给模板显示 html 可以通过 插件表达式 data 属性绑定 property data 插值表达式 data 变量调用 html 里写 p tracyName
  • hyper-v克隆win10虚拟机后无法联网的解决方案

    克隆的虚拟机mac地址是不变的 所以要修改mac地址才行 现在有个更简单的办法 就是直接删除网络适配器 然后重新添加一个网络适配器即可 第一步 先删除原来的网卡 第二步 添加新的网卡 然后确定保存 立即生效
  • vue3.2结合element-plus实现一个全局分页组件

    最近开始学习vue3 0的api语法 通使用vue3 0 element plus搭建一个模板 把常用的组件封装一下 常用的分页组件 通过封装之后 粘贴复制 开箱即用 首先安装vue3 2版本和element plus 分页组件
  • Python-OpenCv-答题卡识别

    前言 用OpenCv进行答题卡的扫描获取信息 其中用到平滑处理 边缘检测 透视变换 坐标点处理 一 轮廓检测 import cv2 import numpy as np def cv show name img cv2 imshow nam
  • 在linux-CentOS7.9中搭建DHCP服务器

    目录 dhcp协议 dhcp分配的过程 在linux系统里搭建一个dhcp服务 给其他机器分配ip地址 具体步骤 1 安装dhcp相关的软件包 2 拷贝样例文件到 etc dhcp目录下 3 编辑配置文件 4 启动dhcp服务器 5 查看d
  • 深入了解golang 的channel

    文章目录 1 channel 是什么 channel的特点 2 channel 的数据结构 hchan 等待队列和发送队列的类型包装 sudog 3 channel 分类 有缓冲channel 无缓冲channel 4 channel 的创
  • STOCHRSI 指标理解

    STOCHRSI 指标理解 这几天帮一个朋友解决一个关于指标的问题 这个指标就是 STOCHRSI 在网上查了很多资料 中文的真是甚少 而且仅有的也不是讲的很清楚 对于我这样的 交易小白 简直是天书 不过只要研究多少会有点收获的 下面分享下
  • 7月7日下午!GLM大模型技术前沿与应用探索

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 随着AIGC时代的到来 大型语言模型逐渐成为学术界和工业界的关注焦点 近期 各种大语言模型的涌现给自然语言处理领域的研究带来了诸多挑战 也逐渐对计算机视觉和计算机生物等领域产生了
  • 解析CAN的J1939协议PDU报文

    PF用来确定PDU格式 0 239表示PDU1格式 240 255表示格式2 PDU1格式报文表示向特定或全局地址发送 PDU2格式报文表示向全局地址发送 PS由PF决定其含义 DA表示报文要发送的目标地址 GE表示PS在PDU2中与PF的
  • 面试官问你为什么选择做客服_在线客户服务-您的选择

    面试官问你为什么选择做客服 On the Web news travels fast and a good customer testimonial is worth its weight in gold If a client feels
  • Java并发编程实战——彻底理解volatile

    文章目录 volatile作用 volatile实现原理 volatile的happens before关系 volatile的内存语义 volatile重排序与JMM内存屏障 volatile的使用误区 volatile的适用场景 vol
  • CI/CD一般流程图

    CI CD的流水线一般由按照一定的逻辑组织工具 下面是一个逻辑图串联工具形成的一个典型的CI CD流程 工具 Bitbucket 代码托管工具 Jenkins 编译工具 Docker 打包工具 Slack Email 通知工具 Artifa
  • .net mvc + vuejs 的项目结构

    net项目结构 程序目录结构 vue操作 前提 安装npm vue vue cli 1 进入控制台窗口 2 进入程序目录 3 运行 vue init webpack webjs 生成webjs及其子目录 4 cd webjs 5 npm i
  • 使用V C ++ 向.exe文件中写入资源

    使用V C 向 exe文件中写入资源 BOOL result HANDLE hFile CreateFile c test htm GENERIC READ FILE SHARE READ NULL OPEN EXISTING FILE A
  • Linux虚拟机增加内存后扩展swap空间( insufficient virtual memory,please increase swap space)

    虚拟内存 swap 的基本概念 虚拟内存 swap 就是将硬盘规划出一个区 间 让内存的数据可以经由硬盘来读取 swap工作原理是 当物理内存不够时 则某些在内存当中所占的程序会暂时被 移动到 swap 中 让物理内存可以被更需要的程序来优
  • 在Qt项目中添加pri文件

    在Qt项目框架里 很多人都喜欢用pri文件来管理项目 那么今天就来讲讲这个pri文件 目录 前言 创建pri文件的步骤 一 创建Qt项目 二 创建pri空文件 三 调试 前言 一般我们创建Qt项目工程的时候 都是直接把所有的项目 头文件和资
  • Qt 添加其他目录的资源文件

    添加App目录资源文件的方法 首先 添加 qrc文件 Add New xxx qrc 其次 在qrc文件上添加存在的目录 或者文件 添加其他目录资源文件的方法 如下图步骤
  • 网易一面,痛失30K:为啥用阻塞队列,list不行吗?

    程序员的成长之路 互联网 程序员 技术 资料共享 关注 阅读本文大概需要 5 5 分钟 来自 技术自由圈 本文目录 说在前面 1 什么是阻塞队列 2 主要并发队列关系图 3 阻塞队列和 List Set 的区别是什么 4 阻塞队列和普通Qu