第4章 多线程与并发编程
线程池 · HandlerThread · AsyncTask · Kotlin协程 · 公司侧重点
本章定位:多线程与并发是Android面试的必考核心区,覆盖线程池参数、HandlerThread消息机制、AsyncTask生命周期、Kotlin协程四大技术。字节跳动侧重协程+线程池底层,腾讯系侧重HandlerThread+消息链,阿里系侧重并发容器+性能调优。
四种并发技术核心对比
| 技术 | 核心机制 | 适用场景 | 优点 | 缺点 | 公司偏好 |
|---|---|---|---|---|---|
| 线程池 | 线程复用 + 阻塞队列 | 大量短时任务 | 可控性强、资源复用 | 配置复杂、队列选择 | 字节跳动 |
| HandlerThread | Looper + 串行消息 | 文件IO、DB操作 | 串行安全、生命周期可控 | 单线程、吞吐量有限 | 腾讯系 |
| AsyncTask | 封装线程 + Handler | 简单异步任务 | 使用简便、代码简洁 | 已废弃、易内存泄漏 | 历史项目 |
| Kotlin协程 | 挂起/恢复 + 调度器 | 复杂异步流 | 轻量、结构化并发 | 学习成本、调试复杂 | 字节跳动 |
面试策略:回答多线程问题应遵循"场景→选型→原理→实战"路径。先说明使用场景,再选择合适技术,然后阐述核心原理,最后结合项目经验落地。避免直接背诵参数,要体现技术判断力。
Q1
高频
请详细说明 ThreadPoolExecutor 的核心参数及工作流程。
🎯 面试官考察点:
- 对Java并发包底层源码的理解深度
- 参数配置与业务场景的匹配能力
- 拒绝策略的选型判断力
📐 回答框架:
- 参数说明 — 7个核心参数逐个展开
- 工作流程 — 核心线程→队列→最大线程→拒绝策略
- 拒绝策略 — 4种内置策略及自定义方式
- 场景选型 — CPU密集 vs IO密集的配置差异
💬 示例回答:
核心参数有corePoolSize、maximumPoolSize、keepAliveTime、TimeUnit、workQueue、threadFactory、handler。工作流程:核心线程满→任务入队→队列满→创建新线程至最大→触发拒绝策略。四种策略:AbortPolicy抛异常、CallerRunsPolicy调用线程直接执行、DiscardPolicy静默丢弃、DiscardOldestPolicy丢弃队列最旧任务。IO密集型建议corePoolSize=2n+1,CPU密集型建议n+1。
🔍 可能追问:
- 如何自定义拒绝策略?实现RejectedExecutionHandler接口
- 线程池大小如何动态调整?通过setCorePoolSize/setMaximumPoolSize
- 工作队列如何选择?LinkedBlockingQueue无界易OOM,ArrayBlockingQueue有界需合理设置容量
- 线程池状态有哪些?RUNNING/SHUTDOWN/STOP/TIDYING/TERMINATED
⚠️ 避坑提醒:使用LinkedBlockingQueue无界队列会导致maximumPoolSize失效,任务积压可能OOM;核心线程数过小会触发频繁创建/销毁线程;记得调用shutdown()平滑关闭线程池。