多线程实现阻塞队列

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

 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 }

 

posted @ 2024-07-27 19:11  Venux  阅读(2)  评论(0编辑  收藏  举报