1188. 设计有限阻塞队列

news/2025/10/21 22:25:53/文章来源:https://www.cnblogs.com/clarencezzh/p/19156564

1188. 设计有限阻塞队列

题目描述

实现一个拥有如下方法的线程安全有限阻塞队列:

  • BoundedBlockingQueue(int capacity) 构造方法初始化队列,其中capacity代表队列长度上限。
  • void enqueue(int element) 在队首增加一个element. 如果队列满,调用线程被阻塞直到队列非满。
  • int dequeue() 返回队尾元素并从队列中将其删除. 如果队列为空,调用线程被阻塞直到队列非空。
  • int size() 返回当前队列元素个数。

你的实现将会被多线程同时访问进行测试。每一个线程要么是一个只调用enqueue方法的生产者线程,要么是一个只调用dequeue方法的消费者线程。size方法将会在每一个测试用例之后进行调用。

请不要使用内置的有限阻塞队列实现,否则面试将不会通过。

 

示例 1:

输入:
1
1
["BoundedBlockingQueue","enqueue","dequeue","dequeue","enqueue","enqueue","enqueue","enqueue","dequeue"]
[[2],[1],[],[],[0],[2],[3],[4],[]]输出:
[1,0,2,2]解释:
生产者线程数目 = 1
消费者线程数目 = 1BoundedBlockingQueue queue = new BoundedBlockingQueue(2);   // 使用capacity = 2初始化队列。queue.enqueue(1);   // 生产者线程将1插入队列。
queue.dequeue();    // 消费者线程调用dequeue并返回1。
queue.dequeue();    // 由于队列为空,消费者线程被阻塞。
queue.enqueue(0);   // 生产者线程将0插入队列。消费者线程被解除阻塞同时将0弹出队列并返回。
queue.enqueue(2);   // 生产者线程将2插入队列。
queue.enqueue(3);   // 生产者线程将3插入队列。
queue.enqueue(4);   // 生产者线程由于队列长度已达到上限2而被阻塞。
queue.dequeue();    // 消费者线程将2从队列弹出并返回。生产者线程解除阻塞同时将4插入队列。
queue.size();       // 队列中还有2个元素。size()方法在每组测试用例最后调用。

 

示例 2:

输入:
3
4
["BoundedBlockingQueue","enqueue","enqueue","enqueue","dequeue","dequeue","dequeue","enqueue"]
[[3],[1],[0],[2],[],[],[],[3]]输出:
[1,0,2,1]解释:
生产者线程数目 = 3
消费者线程数目 = 4BoundedBlockingQueue queue = new BoundedBlockingQueue(3);   // 使用capacity = 3初始化队列。queue.enqueue(1);   // 生产者线程P1将1插入队列。
queue.enqueue(0);   // 生产者线程P2将0插入队列。
queue.enqueue(2);   // 生产者线程P3将2插入队列。
queue.dequeue();    // 消费者线程C1调用dequeue。
queue.dequeue();    // 消费者线程C2调用dequeue。
queue.dequeue();    // 消费者线程C3调用dequeue。
queue.enqueue(3);   // 其中一个生产者线程将3插入队列。
queue.size();       // 队列中还有1个元素。由于生产者/消费者线程的数目可能大于1,我们并不知道线程如何被操作系统调度,即使输入看上去隐含了顺序。因此任意一种输出[1,0,2]或[1,2,0]或[0,1,2]或[0,2,1]或[2,0,1]或[2,1,0]都可被接受。

解法

JAVA

import java.util.*;
import java.util.concurrent.locks.*;public class BoundedBlockingQueue {private final Queue<Integer> queue;private final int capacity;private final Lock lock = new ReentrantLock();private final Condition notFull = lock.newCondition();private final Condition notEmpty = lock.newCondition();public BoundedBlockingQueue(int capacity) {this.capacity = capacity;this.queue = new LinkedList<>();}// 入队操作:如果队列满则阻塞等待public void enqueue(int element) throws InterruptedException {lock.lock();try {while (queue.size() == capacity) {notFull.await();  // 等待直到有空位}queue.offer(element);// 插入后,队列非空,通知消费者notEmpty.signal();} finally {lock.unlock();}}// 出队操作:如果队列空则阻塞等待public int dequeue() throws InterruptedException {lock.lock();try {while (queue.isEmpty()) {notEmpty.await(); // 阻塞,释放锁,等待直到有元素。等待线程会被唤醒并重新尝试获取锁}int val = queue.poll();// 出队后,队列不满,通知生产者notFull.signal();return val;} finally {lock.unlock();}}// 返回当前队列大小public int size() {lock.lock();try {return queue.size();} finally {lock.unlock();}}
}

解法二:

import java.util.LinkedList;
import java.util.Queue;public class BoundedBlockingQueue {private final Queue<Integer> queue;private final int capacity;public BoundedBlockingQueue(int capacity) {this.capacity = capacity;this.queue = new LinkedList<>();}// 入队:队列满时等待public synchronized void enqueue(int element) throws InterruptedException {// 当队列已满,等待while (queue.size() == capacity) {wait(); // 释放锁并等待被唤醒}// 插入元素queue.offer(element);// 插入后队列非空,通知消费者notifyAll(); }// 出队:队列空时等待public synchronized int dequeue() throws InterruptedException {// 当队列为空,等待while (queue.isEmpty()) {wait(); // 释放锁并等待被唤醒}// 出队操作int val = queue.poll();// 出队后队列不满,通知生产者notifyAll();return val;}// 当前队列大小public synchronized int size() {return queue.size();}
}

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

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

相关文章

MySQL 创建和授权用户

查看所有用户 SELECT user, host FROM mysql.user;查看指定用户的权限 SELECT * FROM mysql.user WHERE user=root创建和授权用户创建一个用户CREATE USER readonly@% IDENTIFIED BY 123456;给用户赋予只读权限GRANT S…

MySQL分页解决方案

一、深分页问题背景 当分页偏移量(OFFSET)过大时(如LIMIT 100000, 20),MySQL需要扫描并丢弃前100,000条记录,导致:查询性能急剧下降 服务器资源浪费 响应时间变长二、解决方案详解 1. 游标查询(Cursor-based P…

二维坐标旋转公式推导

二维坐标旋转公式一、核心概念 在二维坐标系中,一个点围绕某个旋转中心旋转时,其坐标会发生变化。 旋转可分为两种情况:绕坐标原点 (0,0) 旋转 绕任意点 (cx, cy) 旋转推导基于三角函数与极坐标的关系。二、绕原点 …

Failed to resolve: org.webrtc:google-webrtc:1.0.32006

参考文章:https://blog.csdn.net/rosyrays1/article/details/148427678 这是一个在安卓端实现音视频功能时遇到的问题 解决方案2: gradle dependencies方式: 使用一些开源社区自制仓库的webrtc包名 比如这个(亲测可…

云计算简单算法练习题

云计算简单算法练习题 No1 LCR 128. 库存管理 I 仓库管理员以数组 stock 形式记录商品库存表。stock[i] 表示商品 id,可能存在重复。原库存表按商品 id 升序排列。现因突发情况需要进行商品紧急调拨,管理员将这批商品…

机器学习到深度学习发展历程

一、传统机器学习时代(2000-2012) 这一时期代表了深度学习革命前夕的机器学习黄金时代。支持向量机、决策树集成方法等技术在理论和实践上都达到了成熟,为后续深度学习的发展提供了重要的理论基础和实践经验。 支持…

Java三大特性

OOP 面向对象三大特性:封装、继承、多态、(抽象) 1.封装 只暴露对象的公开属性和方法,无法看到内部实现过程;对象功能内聚,模块之间的耦合降低,更有维护性。 设计模式七大原则之一的迪米特原则,是对封装的具体要…

日总结 15

C# 和 Java 作为两种主流的面向对象编程语言,虽语法相似(均源于 C 系),但在设计目标、生态、特性等方面差异显著,核心区别可总结如下:历史与定位 C#:微软 2000 年推出,早期绑定 Windows 的.NET Framework,后通…

[CF 516 E] Drazil and His Happy Friends

A 侧有 \(n\) 个点,B 侧有 \(m\) 个点,从 \(0\) 开始标号。已知初始有若干黑点,其它都是白点。第 \(i\)(\(i \ge 0\))时刻,若 A 的第 \(i \bmod n\) 个点和 B 的第 \(i \bmod m\) 个点中存在一个黑色的点,则两个…

NVIDIA Triton服务器漏洞危机:攻击者可远程执行代码,AI模型最高权限告急

NVIDIA Triton服务器漏洞危机:攻击者可远程执行代码,AI模型最高权限告急漏洞概述NVIDIA公司面向Windows和Linux系统的Triton Inference Server(一个用于大规模运行人工智能模型的开源平台)近日披露了一组安全漏洞,…

高级程序设计第二次作业

姓名:王志勇 学号:102500434 3.11编程题第一到第八题: 1. 2. 3. 4. 5. 6. 7. 8. 3.1-3.5,3.8-3.9的示例程序结果输出: 3.1 3.2 3.3 3.4 3.5 3.8 3.9

10月21日日记

1.今天进行工程实训,了解机床操作 2.明天学习高数 3.哈希冲突有哪些解决方法?哪种效率最高?

home-assistant.-Adding integrations

Edit the dashboard(编辑仪表板) Dashboards are customizable pages to display information about your smart home devices.Dashboards, cards, and views The screenshot shows an Overview dashboard with man…

lgP14254 分割(divide)

lg scp-s模拟赛T2 场上计数的部分调了很久没过。 主要讲一下场上的思路吧,可能有点乱。 首先可以发现每个节点子树的深度集合可以表示成一个上界和一个下界。 下界是节点本身的深度,上界是节点子树里最深的节点的深度…

idea快捷键和注释、关键字、数据类型

idea快捷键和注释、关键字、数据类型快捷键 psvm:public static void main(String[] args) {} sout:System.out.println(); 注释 单行注释:// 多行注释:/* / 文档注释: /* * * */ 关键字基本数据…

Windows版本的Emacs如何选择字体(Linux也一样,KIMI)

Windows版本的Emacs如何选择字体(Linux也一样,KIMI)TITLE: Windows版本的Emacs如何选择字体(Linux也一样,KIMI) 本文为和AI大模型助手KIMI的对话内容,仅供参考。 Emacs应该如何选择字体? User: Windows版本的E…

2025.10.21

今天上午工程实训课学习激光加工打印名牌和在手机壳上刻字,中午吃了小蛋糕,下午帮学长拿资料,所以早起了一会去教室,晚上吃了水果,然后上养生与健身课。

化学同位素

质子数相同而中子数不同的同一元素的不同核素互称为同位素。 例如:氢有三种同位素,氕(H)、氘(D,重氢)、氚(T,超重氢);碳有多种同位素,12C、13C和 14C(有放射性)等。同位素元素图同位素具有相同原子序数的…

equal和hashcode

equal和hashcode目录equal和hashcode核心代码示例hashCode() 方法哈希码哈希码原理equals()与hashcode()的联系图形展示完整的示例代码 核心代码示例 public boolean equals(Object o) {if (this == o) return true;if…

Windows系统内存占用过高,且任务管理器找不到对应进程

Windows系统内存占用过高,且任务管理器找不到对应进程 现象描述 开机后系统卡顿,任务管理器查看内存占比达到90%+,统计APP实际消耗内存远小于标称占比。 解决方案cmd输入resmon打开资源监视器 按照工作集内存占用大…