第4章 多线程编程
依据2017年首版完整目录覆盖23个节点:从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask
第4章 多线程编程
在《第4章 多线程编程》中,本页依据刘望舒《Android进阶之光》独立重构,不复制原文。版本锁定电子工业出版社2017年7月首版、492页、ISBN 9787121315305;正式结构为11章、190个章/节/小节节点。
在《第4章 多线程编程》中,原书处在Android 5.0至7.0、Java与Support Library时代,包含AsyncTask、Volley、otto、RxJava早期版本、ButterKnife、Dagger 2和Data Binding。课程先复现历史机制,再以AndroidX、协程/Flow、现代架构组件作迁移对照。
学习目标
- 能解释“第4章 多线程编程”全部23个正式节点的输入、线程、生命周期与可观察结果。
- 能实现“从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask”的最小可运行切片并保存版本、源码、样本和日志。
- 能区分正确结果、框架便利、隐藏成本和版本差异,并用线程状态轨迹、happens-before断言、锁竞争、队列容量、拒绝策略、取消与主线程回调日志验收。
- 能设计反例推翻“用volatile替代复合操作同步,或让无界队列和AsyncTask越过页面生命周期继续工作”,写出2017年机制到现代Android的迁移与回退条件。
机制总览
第4章 多线程编程:机制路径
- 1
从可观察行为开始
本单元主线是从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask。交互管线逐项选择目录节点,反例实验切换正常、配置变化、线程竞争、所有者销毁和版本漂移,证据门要求目录、行为、线程、生命周期与迁移全部通过。
- 2
最小实现与边界
if (Thread.currentThread().isInterrupted) return
- 3
证据解释
第一份证据是行为基线。固定Android版本、依赖版本、构建类型、输入数据和页面生命周期,完整记录“从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask”从入口到结果的顺序。除了成功输出,还要保存回调线程、对象身份、队列或订…
章级决策实验
第4章 多线程编程:机制与证据
切换《第4章 多线程编程》的三个关键教学阶段,先解释机制,再用运行与失败证据验证结论。
选择推理阶段
当前阶段 · 从可观察行为开始
本单元主线是从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask。交互管线逐项选择目录节点,反例实验切换正常、配置变化、线程竞争、所有者销毁和版本漂移,证据门要求目录、行为、线程、生命周期与迁移全部通过。
可核验证据
在固定 Android 5–7 基线运行「从可观察行为开始」的正常与单变量失败样本,保存回调线程、状态快照、资源释放和 AndroidX/现代 API 迁移对照。
学完《第4章 多线程编程》后,应能从输入和前置条件推导状态变化,并用可重复的构建、运行或边界测试证明结果。
失效—证据矩阵
第4章 多线程编程:失效与核验
从可观察行为开始
典型失效
若把「从可观察行为开始」只写成旧框架 API 示例而不说明线程、生命周期、状态所有者与现代迁移边界,正常演示会在取消、重建或版本升级后失效。
核验证据
在固定 Android 5–7 基线运行「从可观察行为开始」的正常与单变量失败样本,保存回调线程、状态快照、资源释放和 AndroidX/现代 API 迁移对照。
最小实现与边界
典型失效
若把「最小实现与边界」只写成旧框架 API 示例而不说明线程、生命周期、状态所有者与现代迁移边界,正常演示会在取消、重建或版本升级后失效。
核验证据
在固定 Android 5–7 基线运行「最小实现与边界」的正常与单变量失败样本,保存回调线程、状态快照、资源释放和 AndroidX/现代 API 迁移对照。
证据解释
典型失效
若把「证据解释」只写成旧框架 API 示例而不说明线程、生命周期、状态所有者与现代迁移边界,正常演示会在取消、重建或版本升级后失效。
核验证据
在固定 Android 5–7 基线运行「证据解释」的正常与单变量失败样本,保存回调线程、状态快照、资源释放和 AndroidX/现代 API 迁移对照。
从可观察行为开始
↡一个线程写入共享状态后其他线程按内存模型规则观察到更新的性质、↡操作整体不可被其他线程观察到中间状态的性质、↡容量或元素条件不满足时让生产者或消费者等待的线程安全队列、↡复用有限工作线程并通过队列和拒绝策略调度任务的执行器、↡通过中断标志与阻塞方法让任务响应取消而非强制终止线程的协议构成本页的分析词汇。先预测一次输入会穿过哪些对象、线程、队列、View或语言边界,再运行正常与失败样本;没有版本和原始证据的“源码原理”不能复查。
本单元主线是从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask。交互管线逐项选择目录节点,反例实验切换正常、配置变化、线程竞争、所有者销毁和版本漂移,证据门要求目录、行为、线程、生命周期与迁移全部通过。
最小实现与边界
val executor = ThreadPoolExecutor(
2, 4, 30, TimeUnit.SECONDS,
ArrayBlockingQueue<Runnable>(64),
ThreadPoolExecutor.CallerRunsPolicy()
)
if (Thread.currentThread().isInterrupted) return在《第4章 多线程编程》中,实现后用固定输入记录输出、线程名、生命周期、异常和资源释放。再构造错误输入、取消、旋转、后台切前台及低版本设备,验证便利框架没有隐藏所有权问题。
data class AndroidProbe(
val apiLevel: Int,
val ownerActive: Boolean,
val callbackThread: String,
val resultStable: Boolean
)
check(probe.ownerActive && probe.resultStable)证据解释
第一份证据是行为基线。固定Android版本、依赖版本、构建类型、输入数据和页面生命周期,完整记录“从线程状态、中断和安全终止进入锁、条件、同步、volatile、阻塞队列、线程池并解析Android 7.0 AsyncTask”从入口到结果的顺序。除了成功输出,还要保存回调线程、对象身份、队列或订阅状态以及释放日志;否则无法判断升级后的差异来自业务代码、框架实现还是测试环境。
第二份证据是反例。针对“用volatile替代复合操作同步,或让无界队列和AsyncTask越过页面生命周期继续工作”构造至少一个可重复失败:在配置变化、快速重复输入、网络超时、后台切换或所有者销毁时观察错位、重复、泄漏和迟到回调。反例必须写明预期拒绝条件;只展示正常路径会掩盖框架最重要的所有权边界。
第三份证据是源码定位。先锁定仓库标签和库版本,再从公开入口沿实际调用追踪,不跨版本拼接类名。每次跨线程、跨进程或跨Java/Native边界,都记录调用方、被调用方、数据形态、错误返回和资源归属。线程状态轨迹、happens-before断言、锁竞争、队列容量、拒绝策略、取消与主线程回调日志应能让另一位读者在相同版本上重建同一条链。
在《第4章 多线程编程》中,第四份证据是迁移对照。现代API解决的问题可能相同,但取消、缓存、状态恢复、线程和错误语义未必一致。迁移时保持输入和验收不变,一次只替换一个组件;新旧结果不一致时先解释差异,再决定适配或回退,不能用“新版推荐”跳过历史行为验证。
迁移账本
原书节点: 第4章 多线程编程
历史基线: Android 5.0—7.0 / Java / Support Library
现代候选: 一次只替换一个API或框架
不变量: 业务结果、线程、生命周期、错误与资源释放
证据: 线程状态轨迹、happens-before断言、锁竞争、队列容量、拒绝策略、取消与主线程回调日志
回退: 任一不变量失败即恢复历史实现本章回顾
从一个真实输入复盘:它由谁接收、在哪个线程执行、状态和对象归谁所有、何时取消或释放、低版本与异常路径如何表现。然后用线程状态轨迹、happens-before断言、锁竞争、队列容量、拒绝策略、取消与主线程回调日志重放;无法复现的结论退回实验阶段。
复习与独立交接
练习
问题 1:为什么本页必须保留23个目录节点?
问题 2:最小正确性合同是什么?
问题 3:怎样构造最有效的反例?
问题 4:为什么只读源码类名不够?
问题 5:怎样迁移而不改写原书?
问题 6:独立交接需要什么?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- 可见性
一个线程写入共享状态后其他线程按内存模型规则观察到更新的性质。
- 原子性
操作整体不可被其他线程观察到中间状态的性质。
- 阻塞队列
容量或元素条件不满足时让生产者或消费者等待的线程安全队列。
- 线程池
复用有限工作线程并通过队列和拒绝策略调度任务的执行器。
- 中断协作
通过中断标志与阻塞方法让任务响应取消而非强制终止线程的协议。
← 上一页:第3章 View体系与自定义View · 下一页:第5章 网络编程与网络框架 →
原版目录概念补充核对
以下条目补齐官方目录中容易被示例主线掩盖的概念。它们不重复罗列目录,而是明确每项概念的机制、适用边界和验收证据。
4.1 线程基础:机制、边界与证据
第4章 多线程编程中的4.1 线程基础涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.1.1 进程与线程:机制、边界与证据
第4章 多线程编程中的4.1.1 进程与线程涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.1.2 线程的状态:机制、边界与证据
第4章 多线程编程中的4.1.2 线程的状态涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.1.3 创建线程:机制、边界与证据
第4章 多线程编程中的4.1.3 创建线程涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.1.4 理解中断:机制、边界与证据
第4章 多线程编程中的4.1.4 理解中断应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.1.5 安全地终止线程:机制、边界与证据
第4章 多线程编程中的4.1.5 安全地终止线程涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.2 同步:机制、边界与证据
第4章 多线程编程中的4.2 同步涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.2.1 重入锁与条件对象:机制、边界与证据
第4章 多线程编程中的4.2.1 重入锁与条件对象应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.2.2 同步方法:机制、边界与证据
第4章 多线程编程中的4.2.2 同步方法涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.2.3 同步代码块:机制、边界与证据
第4章 多线程编程中的4.2.3 同步代码块涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.2.4 volatile:机制、边界与证据
第4章 多线程编程中的4.2.4 volatile应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.3 阻塞队列:机制、边界与证据
第4章 多线程编程中的4.3 阻塞队列应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.3.1 阻塞队列简介:机制、边界与证据
第4章 多线程编程中的4.3.1 阻塞队列简介应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.3.2 Java中的阻塞队列:机制、边界与证据
第4章 多线程编程中的4.3.2 Java中的阻塞队列应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.3.3 阻塞队列的实现原理:机制、边界与证据
第4章 多线程编程中的4.3.3 阻塞队列的实现原理应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.3.4 阻塞队列的使用场景:机制、边界与证据
第4章 多线程编程中的4.3.4 阻塞队列的使用场景应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.4 线程池:机制、边界与证据
第4章 多线程编程中的4.4 线程池涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.4.1 ThreadPoolExecutor:机制、边界与证据
第4章 多线程编程中的4.4.1 ThreadPoolExecutor应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。
4.4.2 线程池的处理流程和原理:机制、边界与证据
第4章 多线程编程中的4.4.2 线程池的处理流程和原理涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.4.3 线程池的种类:机制、边界与证据
第4章 多线程编程中的4.4.3 线程池的种类涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.5 AsyncTask的原理:机制、边界与证据
第4章 多线程编程中的4.5 AsyncTask的原理涉及任务调度、共享状态、取消和生命周期所有权,回调成功一次不代表旋转或销毁后仍安全。记录线程、消息队列、owner 状态与资源释放,并注入取消、迟到回调或竞争复现失败路径。
4.6 本章小结:机制、边界与证据
第4章 多线程编程中的4.6 本章小结应固定 Android 5.0–7.0、Java 与旧 Support Library 语境,写出输入、状态、线程、生命周期和失败结果。以最小实现和单变量反例保存日志、状态快照与迁移差异。