Java 阻塞队列
BlockingQueue 接口定义了阻塞队列的操作。在本教程中,我们将了解 Java BlockingQueue 接口及其方法。
在本教程中,我们将了解 Java BlockingQueue 接口及其方法。
在 Java 集合框架中,BlockingQueue
接口扩展了 Queue
接口,它定义了阻塞队列的操作。它的操作都是可等待的,直到满足执行的条件。
例如,如果我们想从一个空队列中删除一个元素,那么阻塞队列允许删除操作等待,直到队列中有了可供删除的元素。
BlockingQueue 的实现类
BlockingQueue
是一个接口,只是定义了阻塞队列的行为,而没有实现这些行为。Java 集合框架中提供了 2 个组赛队列的实现类:
我们根据自己的需要选择使用 ArraryBlockingQueue
或 LinkedBlockingQueue
创建阻塞队列。
BlockingQueue<String> animal1 = new ArraryBlockingQueue<>();
BlockingQueue<String> animal2 = new LinkedBlockingQueue<>();
阻塞队列的方法
根据队列是满还是空,阻塞队列的方法可以分为 3 类:
抛出异常的方法
add()
- 在队列末尾插入一个元素到阻塞队列。如果队列已满则抛出异常。element()
- 返回阻塞队列的头部。如果队列为空,则抛出异常。remove()
- 从阻塞队列中移除一个元素。如果队列为空,则抛出异常。
返回一些值的方法
offer()
- 将指定元素插入队列末尾的阻塞队列。如果队列已满则返回false
。peek()
- 返回阻塞队列的头部。如果队列为空则返回null
。poll()
- 从阻塞队列中移除一个元素。如果队列为空则返回null
。
关于 offer() 和 poll()
offer()
和 poll()
方法都可用设置超时时间。也就是说,我们可以将超时时间参数传递。例如,
offer(value, 100, milliseconds)
这里,
value
是要插入队列的元素100
是超时时间,时间单位由第三个参数指定milliseconds
超时时间的时间单位是毫秒。 时间单位可参考枚举类java.util.concurrent.TimeUnit
。
这意味着 offer()
方法将尝试在 100
毫秒内向阻塞队列插入一个元素。如果在 100 毫秒内无法插入元素,则返回 false
。
阻塞操作的方法
BlockingQueue
还提供了一些方法进行阻塞操作。阻塞方法在没有满足条件的时候会一直等待,直到满足跳进。
put()
- 向阻塞队列插入一个元素。如果队列已满,它将等待队列有空间插入元素。take()
- 从阻塞队列中移除并返回一个元素。如果队列为空,它会一直等到队列中有要删除的元素。
ArrayBlockingQueue 中 BlockingQueue 的实现
ArrayBlockingQueue
类实现了 BlockingQueue
接口,我们可以是用 ArrayBlockingQueue
类创建阻塞队列。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
public class Main {
public static void main(String[] args) {
// Create a blocking queue using the ArrayBlockingQueue
BlockingQueue<Integer> numbers = new ArrayBlockingQueue<>(5);
try {
// 插入元素到阻塞队列
numbers.put(2);
numbers.put(1);
numbers.put(3);
System.out.println("BLockingQueue: " + numbers);
// 从阻塞队列删除元素
int removedNumber = numbers.take();
System.out.println("Removed Number: " + removedNumber);
} catch (Exception e) {
e.getStackTrace();
}
}
}
输出
BLockingQueue: [2, 1, 3]
Removed Number: 2
要了解 ArrayBlockingQueue
更多信息,请访问 Java ArrayBlockingQueue 类。
何时使用阻塞队列?
在 Java 中, BlockingQueue
被认为是线程安全的集合,在多线程环境中对你会有所帮助。
阻塞队列一个常用的场景是在生产者消费者模式中。
我们实现生产者消费者模式的时候,可以使用阻塞队列作为中间的产品仓库,生产者线程生产了产品之后会将产品放入仓库,消费者线程在需要的时候从仓库拿走产品。
如果生产的快而消费的慢,那么仓库(队列)满了之后,生产者线程就要等待仓库有空间才能放入新的产品。
如果生产的慢而消费的快,那么仓库(队列)空了之后,消费者线程就要等待仓库中有了产品之后才能拿走。