首页 > 其他分享 >多线程实现阻塞队列

多线程实现阻塞队列

时间:2024-07-27 19:19:02浏览次数:5  
标签:队列 lock 阻塞 private queue finally 多线程 public

今天面试被问到了,多线程实现阻塞队列,记录一下。

 1 import java.util.LinkedList;
 2 import java.util.Queue;
 3 import java.util.concurrent.locks.Condition;
 4 import java.util.concurrent.locks.ReentrantLock;
 5 
 6 public class FixedSizeBlockingQueue<T> {
 7     private final int capacity;
 8     private final Queue<T> queue;
 9     private final ReentrantLock lock;
10     private final Condition notFull;
11     private final Condition notEmpty;
12     private volatile boolean isClosed = false; // 用于标记队列是否已关闭
13 
14     public FixedSizeBlockingQueue(int capacity) {
15         this.capacity = capacity;
16         this.queue = new LinkedList<>();
17         this.lock = new ReentrantLock();
18         this.notFull = lock.newCondition();
19         this.notEmpty = lock.newCondition();
20     }
21 
22     public void put(T item) throws InterruptedException {
23         lock.lock();
24         try {
25             while (queue.size() == capacity || isClosed) { // 检查队列是否已满或已关闭
26                 if (isClosed) {
27                     throw new IllegalStateException("Queue is closed");
28                 }
29                 notFull.await();
30             }
31             queue.add(item);
32             notEmpty.signal();
33         } finally {
34             lock.unlock();
35         }
36     }
37 
38     public T take() throws InterruptedException {
39         lock.lock();
40         try {
41             while (queue.isEmpty()) {
42                 notEmpty.await();
43             }
44             T item = queue.poll();
45             notFull.signal();
46             return item;
47         } finally {
48             lock.unlock();
49         }
50     }
51 
52     // 返回队列中当前元素的数量
53     public int size() {
54         lock.lock();
55         try {
56             return queue.size();
57         } finally {
58             lock.unlock();
59         }
60     }
61 
62     // 关闭队列并返回所有剩余元素  
63     public Collection<T> close() throws InterruptedException {  
64         lock.lock();  
65         try {  
66             isClosed = true;  
67             // 将队列中的剩余元素转移到remainingElements集合中  
68             remainingElements.addAll(queue);  
69             queue.clear(); // 清空队列(可选,取决于你是否还需要访问原始队列对象)  
70   
71             // 唤醒所有等待的put线程(它们将收到IllegalStateException)  
72             notFull.signalAll();  
73   
74             // 返回剩余元素  
75             return new ArrayList<>(remainingElements); // 返回一个新的列表副本,以避免外部修改  
76         } finally {  
77             lock.unlock();  
78         }  
79     }  
80   
81     // 一个可选的方法,用于在队列关闭后检查是否有剩余元素  
82     public boolean hasRemainingElements() {  
83         lock.lock();  
84         try {  
85             return !remainingElements.isEmpty();  
86         } finally {  
87             lock.unlock();  
88         }  
89     }  
90 
91 
92 }

 

       

标签:队列,lock,阻塞,private,queue,finally,多线程,public
From: https://www.cnblogs.com/ccsu-kid/p/18327361

相关文章

  • 第十天|栈与队列| 232.用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047. 删除字符串
    目录232.用栈实现队列225.用队列实现栈两个队列模拟栈实现思路1:实现思路2:实现思路3:一个队列模拟栈实现思路1:实现思路2:实现思路3:20.有效的括号1047.删除字符串中的所有相邻重复项方法1:使用Deque堆栈方法2:用字符串直接当作栈方法3:双指针Day10学习到用栈来解......
  • RT-Thread多线程
    RT-Thread启动流程分析线程的状态初始状态:线程刚开始创建,还没开始运行时就处于,初始状态。就绪状态:在就绪状态下,线程按照优先级排队,等待被执行。运行状态:线程正在运行,在单核系统中,只有rt_thread_self()函数返回的线程处于运行状态,但多核系统下,运行的线程不止一个。......
  • day11 栈与队列
    任务150.逆波兰表达式求值思路用栈保存操作数,遇到操作符,将操作数弹出并处理。注意除法的逻辑classSolution:defevalRPN(self,tokens:List[str])->int:s=[]fromoperatorimportadd,sub,mulop_dic={'+':add,'-':sub}f......
  • C++多线程基本使用方式
    一、线程创建        创建线程的函数  thread t(函数名f,函数f的参数) 或者 用lambda表达式代码:#include<iostream>#include<thread>#include<vector>usingnamespacestd;voidoutput(stringinput,inta){ cout<<input<<endl; cout<<a......
  • 19.延迟队列优化
    问题前面所讲的延迟队列有一个不足之处,比如现在有一个需求需要延迟半个小时的消息,那么就只有添加一个新的队列。那就意味着,每新增一个不同时间需求,就会新创建一个队列。解决方案应该讲消息的时间不要跟队列绑定,应该交给消息的生产者,由发送消息来指定延迟时间。这样就可以定......
  • 秒杀优化-基于阻塞队列实现秒杀优化
    秒杀优化VoucherOrderServiceImpl修改下单动作,现在我们去下单时,是通过lua表达式去原子执行判断逻辑,如果判断我出来不为0,则要么是库存不足,要么是重复下单,返回错误信息,如果是0,则把下单的逻辑保存到队列中去,然后异步执行@Slf4j@ServicepublicclassVoucherOrderServiceImplex......
  • 单调栈和单调队列
    单调栈和单调队列P5788#include<bits/stdc++.h>usingnamespacestd;constintN=3e6+5;intn,a[N],ans[N],top,stk[N];intmain(){ scanf("%d",&n); for(inti=1;i<=n;++i){ scanf("%d",&a[i]); while(top>0&&a[stk[......
  • 分布式集群与多线程高并发
     后台数据的处理语言有很多,Java是对前端采集的数据的一种比较常见的开发语言。互联网移动客户端的用户量特别大,大量的数据处理需求应运而生。可移动嵌入式设备的表现形式很多,如PC端,手机移动端,智能手表,Google眼镜等。Server2client的互联网开发模式比较常见,有一种新的数......
  • 直播平台搭建,需要实现的核心要素之队列
    直播平台搭建,需要实现的核心要素之队列队列的实现在直播平台搭建中,队列的实现分为队列的定义和操作,如前所述,队列是元素的有序集合,添加操作发生在其尾部,移除操作则发生在头部。队列的操作顺序是先进先出(FIFO),它支持以下操作。Queue():创建一个空队列。它不需要参数,且会......
  • java多线程把数据迁移到不同数据库中
    publicvoidsync_table_test_thread()throwsSQLException,InterruptedException{    longstart=System.currentTimeMillis();    SimpleDateFormatformat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");    //获取要迁移oracle表数据库......