0%

安卓中线程池的创建

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
在安卓中,安全使用线程池是保证应用性能、避免 ANR 和内存泄漏的重要手段。

1️⃣ 为什么要用线程池

避免频繁创建和销毁线程,线程创建成本高。

限制线程数量,避免系统过载。

复用线程,提高性能。

安卓开发中常用线程池有两类:

Executors 提供的便捷方法:如 newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor。

自定义 ThreadPoolExecutor:灵活配置核心线程数、最大线程数、队列大小、拒绝策略。

2️⃣ 常用线程池写法
① 固定线程池(FixedThreadPool)
ExecutorService fixedPool = Executors.newFixedThreadPool(4); // 固定4个线程

fixedPool.execute(() -> {
// 耗时任务
doHeavyTask();
});


适合:任务数量大但线程数可控的情况。

② 缓存线程池(CachedThreadPool)
ExecutorService cachedPool = Executors.newCachedThreadPool();

cachedPool.execute(() -> {
doHeavyTask();
});


特点:有新任务就创建线程,空闲线程 60s 后销毁。

适合:执行短时异步任务,数量不确定。

风险:任务过多会无限开线程 → OOM。

③ 单线程池(SingleThreadExecutor)
ExecutorService singlePool = Executors.newSingleThreadExecutor();
singlePool.execute(() -> {
// 顺序执行任务
});


特点:任务按顺序执行,保证顺序性。

适合:任务必须按顺序执行的场景,比如写文件、写数据库。

④ 自定义线程池(ThreadPoolExecutor)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, // 核心线程数
8, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // 队列大小
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);


优点:灵活可控。

拒绝策略:

AbortPolicy → 抛异常

CallerRunsPolicy → 在调用者线程执行

DiscardPolicy → 丢弃任务

DiscardOldestPolicy → 丢弃最老任务

3️⃣ 安全使用线程池的注意点

避免 UI 更新在子线程

executor.execute(() -> {
// 耗时任务
String result = doHeavyTask();

// UI更新
runOnUiThread(() -> textView.setText(result));
});


避免线程泄漏

Activity/Fragment 销毁时要关闭线程池:

@Override
protected void onDestroy() {
super.onDestroy();
executor.shutdownNow(); // 停止所有任务
}


使用有限队列和核心线程数

防止任务无限堆积,导致 OOM。

结合生命周期感知组件

可以用 ViewModel + LiveData / RxJava / Coroutine 来管理线程和 UI 更新。

4️⃣ 推荐组合方式

IO密集型任务(网络请求、文件读写):

ExecutorService ioPool = Executors.newCachedThreadPool();


CPU密集型任务(计算):

int cpuCount = Runtime.getRuntime().availableProcessors();
ExecutorService cpuPool = Executors.newFixedThreadPool(cpuCount);