【JAVA高级面试题】运用锁机制实现一个自定义的阻塞队列

文章目录

    • 前言
    • 实战演示
    • 写在最后

前言

前几天看见一个高级Java面试题,我觉得很有代表意义。既考察了面试者的基本锁机制运用,也了解了阻塞队列的产生实现原理。先分享出来,以供鉴赏。

面试题:实现一个自定义的阻塞队列,它应该支持以下功能:
添加元素到队列末尾(如果队列已满,则阻塞添加线程直到有空间)
从队列头部移除元素(如果队列为空,则阻塞获取元素的线程直到有元素可消费)
查询队列是否为空
查询队列是否已满
要求使用Java的ReentrantLock和Condition类来实现线程间的同步。

实战演示

既然题目说到了使用Java的ReentrantLock和Condition类来实现线程间的同步,也就为我们指明了方向,直接可以按照题目的思路进行编码。当然,如果题目没有要求使用技术点,你是否知道还有哪些方式可以实现这个阻塞队列呢?
在这里插入图片描述

自定义阻塞队列编码如下:

/*** CustomBlockingQueue* @author senfel* @date 2024/2/21 12:50*/
public class CustomBlockingQueue<T> {private final LinkedList<T> queue = new LinkedList<>();private final int capacity;private final ReentrantLock lock = new ReentrantLock();private final Condition notEmpty = lock.newCondition();private final Condition notFull = lock.newCondition();public CustomBlockingQueue(int capacity) {this.capacity = capacity;}/*** put* @author senfel* @date 2024/2/21 12:52* @return void*/public void put(T item) throws InterruptedException {lock.lock();try {while (queue.size() == capacity) {notFull.await();}if (queue.isEmpty()) {notEmpty.signal(); // 如果之前有等待的消费者,现在可以唤醒了}queue.addLast(item);} finally {lock.unlock();}}/*** take* @author senfel* @date 2024/2/21 12:59* @return void*/public T take() throws InterruptedException {lock.lock();try {while (queue.isEmpty()) {notEmpty.await();}if (queue.size() == capacity) {notFull.signal(); // 如果之前有等待的生产者,现在可以唤醒了}return queue.removeFirst();} finally {lock.unlock();}}public boolean isEmpty() {lock.lock();try {return queue.isEmpty();} finally {lock.unlock();}}public boolean isFull() {lock.lock();try {return queue.size() == capacity;} finally {lock.unlock();}}
}

写在最后

这个CustomBlockingQueue类使用了Java并发包中的ReentrantLock作为锁机制,并通过其条件变量notEmpty和notFull分别管理队列空和队列满的情况。当队列满时,调用put方法会阻塞,直到有空间;当队列空时,调用take方法也会阻塞,直到有元素可消费。同时,当添加或删除元素改变队列状态时,会适当调整对应的条件变量以唤醒等待的线程。

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

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

相关文章

React 事件处理 ( this问题 参数传递 ref)

React事件的命名采用小驼峰方式&#xff08;cameCase&#xff09;,而不是小写 使用JSX语法时你需要传入一个函数作为事件处理函数&#xff0c;而不是一个字符串 你不能通过返回false 的方式阻止默认行为。你必须显示式的使用preventDefault 1 this 需要谨慎对待JSX回调函数中的…

Linux的Ubuntu的APT使用

Linux的Ubuntu的APT使用 apt 介绍 apt 是 Advanced Packaging Tool 的简称&#xff0c;是一款安装包管理工具。在 Ubuntu 下&#xff0c;我们可以使用 apt 命令进行软件包的安装、删除、清理等&#xff0c;类似于 Windows 中的软件管理工具。 Ubuntu 软件操作的相关命令 su…

Android 面试问题 2024 版(其二)

Android 面试问题 2024 版&#xff08;其二&#xff09; 六、多线程和并发七、性能优化八、测试九、安全十、Material设计和 **UX/UI** 六、多线程和并发 Android 中的进程和线程有什么区别&#xff1f; 答&#xff1a;进程是在自己的内存空间中运行的应用程序的单独实例&…

Maven的下载安装配置教程

一、简单了解一下什么是Maven Maven就是一款帮助程序员构建项目的工具&#xff0c;我们只需要告诉Maven需要哪些Jar 包&#xff0c;它会帮助我们下载所有的Jar&#xff0c;极大提升开发效率。 1.Maven翻译为“专家“&#xff0c; ”内行”的意思&#xff0c;是著名Apache公司下…

Unity基于AssetBundle资源管理流程详解

在Unity游戏开发中&#xff0c;资源管理是一个非常重要的环节。随着游戏的发展&#xff0c;资源会变得越来越庞大&#xff0c;因此需要一种高效的资源管理方式来减少内存占用和加快加载速度。AssetBundle是Unity提供的一种资源打包和加载方式&#xff0c;可以将资源打包成一个独…

Fiddler工具 — 19.Fiddler抓包HTTPS请求(二)

5、查看证书是否安装成功 方式一&#xff1a; 点击Tools菜单 —> Options... —> HTTPS —> Actions 选择第三项&#xff1a;Open Windows Certificate Manager打开Windows证书管理器。 打开Windows证书管理器&#xff0c;选择操作—>查看证书&#xff0c;在搜索…

【Java程序员面试专栏 数据结构】四 高频面试算法题:哈希表

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,一个O(1)查找的利器哈希表,所以放到一篇Blog中集中练习 题目关键字解题思路时间空间两数之和辅助哈希使用map存储出现过的值,key为值大小,value为下标位置,…

船舶维保管理系统|基于springboot船舶维保管理系统设计与实现(源码+数据库+文档)

船舶维保管理系统目录 目录 基于springboot船舶维保管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、船舶列表 2、公告信息管理 3、公告类型管理 4、维保计划管理 5、维保计划类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、…

网络安全-pikachu之SQL注入漏洞(数字型注入)

哦,SQL注入漏洞&#xff0c;可怕的漏洞。 在owasp发布的top10排行榜里&#xff0c;注入漏洞一直是危害排名第一的漏洞&#xff0c;其中注入漏洞里面首当其冲的就是数据库注入漏洞。 一个严重的SQL注入漏洞&#xff0c;可能会直接导致一家公司破产&#xff01; SQL注入漏…

Day3 javaweb开发——登录认证

登录功能 没什么好写的&#xff0c;就是LoginController层里面要注入empService的对象 登录校验&#xff08;重点&#xff09; 没有校验的情况 没有登录之前&#xff0c;访问数据的网址需要跳转到登录页面。 http是无状态的&#xff0c;处理其他业务时没有判断他是否登录 …

Apache POI技术-在Java中的基本使用

Apache POI技术-在Java中的基本使用 文章目录 Apache POI技术-在Java中的基本使用前言一、Apache POI是什么&#xff1f;1.Apache POI简介&#xff1a;2.Apache POI主要包括的模块&#xff1a;3.Apache POI 的应用场景&#xff1a;报表生成&#xff1a;数据导入导出&#xff1a…

HarmonyOS—LocalStorage:页面级UI状态存储

LocalStorage是页面级的UI状态存储&#xff0c;通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内&#xff0c;在页面间共享状态。 本文仅介绍LocalStorage使用场景和相关的装饰器&#xff1a;LocalStorageProp和LocalS…

Docker技术仓库

数据卷 为什么用数据卷&#xff1f; 宿主机无法直接访问容器中的文件容器中的文件没有持久化&#xff0c;导致容器删除后&#xff0c;文件数据也随之消失容器之间也无法直接访问互相的文件 为解决这些问题&#xff0c;docker加入了数据卷机制&#xff0c;能很好解决上面问题…

FPGA模块——IIC接口设计

FPGA模块——IIC接口设计 IIC协议IIC接口代码应用IIC接口的代码 IIC协议 IIC接口代码 module iic_drive#(parameter P_ADDR_WIDTH 16 )( input i_clk ,//模块输入时钟input i_rs…

js-Vue Router 中的方法,父A-子B-子C依次返回,无法返回到A,BC中形成循环跳转解决

1.常用的方法 在 Vue Router 中&#xff0c;有一些常用的方法用于实现路由导航和管理。以下是一些常见的 Vue Router 方法及其作用&#xff1a; push: router.push(location, onComplete, onAbort) 作用&#xff1a;向路由历史记录中添加一个新条目&#xff0c;并导航到指定的路…

十六进制数

1.做一个收电费程序&#xff0c;要求输入使用的电的度数&#xff08;整数&#xff09;以及电费单价&#xff08;实数&#xff09;&#xff0c;输出总的用电费用。 2.提示并输入一个小写字母数据&#xff0c;输出其对应的ASCII值&#xff0c;以及该小写字母对应的大写字母。 3.提…

leetcode hot100组合综合四

本题中&#xff0c;是要求nums中求的总和为target的排列数&#xff0c;因为题中说了&#xff0c;元素顺序不同&#xff0c;则可以视为不同的结果之一。 所以&#xff0c;根据对背包问题的总结&#xff0c;本题中元素可以重复使用&#xff0c;是完全背包并且需要求排列数&#…

Redis之缓存击穿问题解决方案

文章目录 一、书接上文二、介绍三、解决方案1. 单例双检锁2. 缓存预热和定时任务 一、书接上文 Redis之缓存雪崩问题解决方案 二、介绍 缓存击穿就是大量并发访问同一个热点数据&#xff0c;一旦这个热点数据缓存失效&#xff0c;则请求压力都来到数据库。 三、解决方案 1…

嵌入式Qt 计算器核心算法_1

一.表达式分离算法分析 二.分离算法实现 QCalculatorDec.cpp #include "QCalculatorDec.h"#include <QDebug>QCalculatorDec::QCalculatorDec() {m_exp "";m_result "";QQueue<QString> r split("9.11 ( -3 - 1 ) * -5 &…

C#,整数转为短字符串(Short string)的加解密算法与源代码

1 整数转为短字符串的应用 网站生成的动态 URL 往往以内容序列号id为标识与参数&#xff0c;比如&#xff1a; http://www.jerry.com/tom.aspx?id1 使用 Web Rewrite&#xff0c;可以实现网页静态化&#xff0c;称为&#xff1a; http://www.jerry.com/content/1.html 对…