深入理解 LinkedBlockingQueue 队列
在 Android 开发中,我们经常需要处理多线程任务,例如后台数据下载、消息分发、任务调度等。这时候 线程安全的队列 就显得非常重要,而 LinkedBlockingQueue 是 Java/Kotlin 提供的经典选择。
本文将从概念、用法、关键方法、实际应用和示例代码,全面讲解 LinkedBlockingQueue 的使用。
一、什么是 LinkedBlockingQueue?
LinkedBlockingQueue 是 Java 并发包 (java.util.concurrent) 下的阻塞队列实现。它的特点:
链表结构存储:内部通过链表存储元素,插入和删除效率高。
线程安全:支持多线程并发操作,无需额外加锁。
阻塞特性:
当队列满时,生产者线程会阻塞,直到有空间。
当队列空时,消费者线程会阻塞,直到有元素。
可选容量:
可指定最大容量,也可无限容量(默认是 Integer.MAX_VALUE)。
二、关键概念
生产者-消费者模式
LinkedBlockingQueue 非常适合生产者-消费者模式:
生产者线程负责向队列添加任务。
消费者线程负责从队列取出任务执行。
队列作为缓冲区,保证线程安全且无需手动同步。
阻塞 vs 非阻塞
阻塞方法:put() / take()
非阻塞方法:offer() / poll() / peek()
容量控制
队列容量可控,避免无限增长造成内存压力。
三、基本用法(Kotlin 示例)
- 导入包
import java.util.concurrent.LinkedBlockingQueue
- 定义队列
// 有容量限制的队列
val queue = LinkedBlockingQueue<String>(5)
// 无容量限制的队列
val unlimitedQueue = LinkedBlockingQueue<String>()
- 入队操作
// 阻塞入队,如果队列满,会等待
queue.put("任务1")
// 非阻塞入队,队列满返回 false
val success = queue.offer("任务2")
- 出队操作
// 阻塞出队,如果队列空,会等待
val task = queue.take()
// 非阻塞出队,队列空返回 null
val polledTask = queue.poll()
- 查看队列元素
// 查看队头元素,但不移除
val head = queue.peek()
四、结合 Android 的多线程示例
假设我们要在安卓中做一个后台任务队列,生产者产生任务(如网络请求),消费者执行任务(如处理结果)。
class TaskQueueManager {
private val taskQueue = LinkedBlockingQueue<String>(10)
init {
// 启动消费者线程
Thread { consumeTasks() }.start()
}
// 生产任务
fun produceTask(task: String) {
Thread {
try {
taskQueue.put(task) // 队列满会阻塞
Log.d("TaskQueue", "任务入队: $task")
} catch (e: InterruptedException) {
e.printStackTrace()
}
}.start()
}
// 消费任务
private fun consumeTasks() {
while (true) {
try {
val task = taskQueue.take() // 队列空会阻塞
Log.d("TaskQueue", "处理任务: $task")
// 模拟任务处理
Thread.sleep(500)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
使用示例:
val manager = TaskQueueManager()
manager.produceTask("下载图片")
manager.produceTask("上传数据")
manager.produceTask("处理日志")
特点:
生产者和消费者完全解耦。
队列自动控制线程安全。
阻塞队列确保在高并发下不会丢任务。
五、常用方法总结
方法 功能 阻塞特性
put(E e) 入队,如果队列满,阻塞 阻塞
take() 出队,如果队列空,阻塞 阻塞
offer(E e) 入队,不阻塞,队列满返回 false 非阻塞
poll() 出队,不阻塞,队列空返回 null 非阻塞
peek() 查看队头元素,不移除,队列空返回 null 非阻塞
remainingCapacity() 查看剩余可用容量 非阻塞
六、应用场景
后台任务队列:图片下载、上传、文件处理。
消息分发系统:事件通知、日志分发。
生产者-消费者模型:游戏逻辑、AI Agent任务队列。
限流场景:通过指定容量控制并发量。
七、总结
LinkedBlockingQueue 是 Android 开发中非常实用的线程安全队列,尤其适合 生产者-消费者模式 和多线程任务调度。
通过 Kotlin 的简单封装和线程启动方式,可以快速在安卓中实现可靠的任务队列,避免手动同步、线程安全问题,并提供阻塞/非阻塞两种操作模式,非常适合 AI Agent 或后台任务管理。