阻塞队列

持续更新中

BlockingQueue​ BlockingQueue是一个接口,它属于 Java 并发包java.util.concurrent,其用途是在多线程环境下实现线程安全的队列操作。

线程安全:BlockingQueue自身实现了线程安全,多个线程能够同时对队列进行读写操作,无需额外的同步机制。

阻塞操作:定义了若干阻塞方法,当队列满时进行入队操作,或者队列空时进行出队操作,这些方法会让线程进入阻塞状态,直至满足操作条件。

容量限制:部分BlockingQueue的实现类具备容量限制,当队列达到最大容量时,再进行入队操作会被阻塞。

插入元素

add(E e):若队列未满,将元素插入队列尾部,成功则返回true;若队列已满,会抛出IllegalStateException异常。

offer(E e):若队列未满,将元素插入队列尾部,成功则返回true;若队列已满,返回false。

offer(E e, long timeout, TimeUnit unit):在指定时间内尝试将元素插入队列尾部,若成功则返回true;若超时仍未成功,返回false。

put(E e):若队列未满,将元素插入队列尾部;若队列已满,线程会阻塞直至队列有空间。

移除元素

remove():若队列不为空,移除并返回队列头部元素;若队列为空,抛出NoSuchElementException异常。

poll():若队列不为空,移除并返回队列头部元素;若队列为空,返回null。

poll(long timeout, TimeUnit unit):在指定时间内尝试移除并返回队列头部元素,若成功则返回元素;若超时仍未成功,返回null。

take():若队列不为空,移除并返回队列头部元素;若队列为空,线程会阻塞直至队列中有元素。

检查元素

element():若队列不为空,返回队列头部元素,但不移除;若队列为空,抛出NoSuchElementException异常。

peek():若队列不为空,返回队列头部元素,但不移除;若队列为空,返回null。

常见实现类

ArrayBlockingQueue:基于数组实现的有界阻塞队列,在创建时需指定容量,且可选择是否使用公平锁。

LinkedBlockingQueue:基于链表实现的阻塞队列,可指定容量,若不指定则默认为Integer.MAX_VALUE,被视为无界队列。

PriorityBlockingQueue:基于优先级堆实现的无界阻塞队列,队列中的元素会按照自然顺序或者指定的比较器进行排序。

SynchronousQueue:一种特殊的阻塞队列,它不存储元素,每个插入操作必须等待另一个线程的移除操作,反之亦然。

示例代码1234567891011121314151617181920212223242526272829303132333435363738394041424344import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class BlockingQueueExample { public static void main(String[] args) { BlockingQueue queue = new ArrayBlockingQueue<>(10); // 生产者线程 Thread producer = new Thread(() -> { try { for (int i = 0; i < 5; i++) { queue.put(i); System.out.println("Produced: " + i); Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); // 消费者线程 Thread consumer = new Thread(() -> { try { for (int i = 0; i < 5; i++) { Integer item = queue.take(); System.out.println("Consumed: " + item); Thread.sleep(200); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); producer.start(); consumer.start(); try { producer.join(); consumer.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }}