0%

安卓LinkedBlockingQueue消息队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
深入理解 LinkedBlockingQueue 队列

在 Android 开发中,我们经常需要处理多线程任务,例如后台数据下载、消息分发、任务调度等。这时候 线程安全的队列 就显得非常重要,而 LinkedBlockingQueue 是 Java/Kotlin 提供的经典选择。

本文将从概念、用法、关键方法、实际应用和示例代码,全面讲解 LinkedBlockingQueue 的使用。

一、什么是 LinkedBlockingQueue?

LinkedBlockingQueue 是 Java 并发包 (java.util.concurrent) 下的阻塞队列实现。它的特点:

链表结构存储:内部通过链表存储元素,插入和删除效率高。

线程安全:支持多线程并发操作,无需额外加锁。

阻塞特性:

当队列满时,生产者线程会阻塞,直到有空间。

当队列空时,消费者线程会阻塞,直到有元素。

可选容量:

可指定最大容量,也可无限容量(默认是 Integer.MAX_VALUE)。

二、关键概念

生产者-消费者模式
LinkedBlockingQueue 非常适合生产者-消费者模式:

生产者线程负责向队列添加任务。

消费者线程负责从队列取出任务执行。

队列作为缓冲区,保证线程安全且无需手动同步。

阻塞 vs 非阻塞

阻塞方法:put() / take()

非阻塞方法:offer() / poll() / peek()

容量控制
队列容量可控,避免无限增长造成内存压力。

三、基本用法(Kotlin 示例)
1. 导入包
import java.util.concurrent.LinkedBlockingQueue

2. 定义队列
// 有容量限制的队列
val queue = LinkedBlockingQueue<String>(5)

// 无容量限制的队列
val unlimitedQueue = LinkedBlockingQueue<String>()

3. 入队操作
// 阻塞入队,如果队列满,会等待
queue.put("任务1")

// 非阻塞入队,队列满返回 false
val success = queue.offer("任务2")

4. 出队操作
// 阻塞出队,如果队列空,会等待
val task = queue.take()

// 非阻塞出队,队列空返回 null
val polledTask = queue.poll()

5. 查看队列元素
// 查看队头元素,但不移除
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 或后台任务管理。