1. 鸿蒙并发编程概述:进程与线程概念、鸿蒙并发模型、并发编程的应用场景
1.1 进程与线程:别再傻傻分不清
说实话,我刚接触并发编程那会儿,也搞混过进程和线程。你想想看,它们俩到底有啥区别?
进程,说白了就是程序的一次执行。每个进程都有自己的独立内存空间,互不干扰。比如你打开微信,系统就给你分配了一个进程。再打开抖音,又是一个新进程。进程之间想交换数据?得走IPC(进程间通信),挺麻烦的。
线程就不一样了。线程是进程里的执行单元,同一个进程的线程共享内存空间。我习惯把进程比作一个工厂,线程就是工厂里的工人。工人们共享工厂的资源(内存),干活效率高,但也容易打架(数据竞争)。
核心区别一句话:进程是资源分配的最小单位,线程是CPU调度的最小单位。
在鸿蒙系统里,进程和线程的管理方式跟Linux有些相似,但也有自己的特色。鸿蒙的进程模型支持多进程架构,每个应用可以跑在独立的沙箱里,安全性做得不错。
1.2 鸿蒙并发模型:到底怎么玩?
鸿蒙的并发模型,我个人觉得挺有意思的。它不像Java那样只靠线程池,也不像Go那样全靠goroutine。鸿蒙走的是混合路线。
具体来说,鸿蒙提供了三种并发手段:
- TaskPool(任务池):适合CPU密集型任务,自动管理线程池,你只管扔任务进去就行
- Worker(工作线程):适合长时间运行的后台任务,生命周期由你控制
- 线程直接操作:底层能力,一般用不上,除非你要做极致的性能调优
我在项目中遇到过一个问题:用TaskPool处理大量图片压缩任务,结果发现任务排队时间太长。后来我改用Worker,每个Worker专门处理一组图片,性能一下就上来了。嗯,这里要注意——TaskPool适合短平快的任务,Worker适合长周期的任务,别搞反了。
我的建议:新手优先用TaskPool,它帮你处理了线程创建、销毁、复用这些脏活累活。等你对并发模型熟悉了,再考虑用Worker做更精细的控制。
1.3 并发编程的应用场景:什么时候该用?
你可能会问:我写个简单的App,有必要搞并发吗?
当然有必要。我给你列几个常见场景:
| 场景 | 说明 | 推荐方案 |
|---|---|---|
| 网络请求 | 同时请求多个API,避免UI卡死 | TaskPool + 异步回调 |
| 图片/视频处理 | 压缩、滤镜、转码等耗时操作 | Worker(长任务) |
| 数据计算 | 大量数据排序、搜索、统计 | TaskPool(分片处理) |
| 后台定时任务 | 数据同步、日志上传 | Worker + 定时器 |
| UI响应优化 | 避免主线程被阻塞 | 所有耗时操作都扔到子线程 |
我曾经接手过一个项目,主线程里直接做了大量JSON解析,结果用户滑动列表时卡成PPT。后来我把解析逻辑扔到TaskPool里,UI瞬间丝滑了。说白了,凡是可能超过16ms的操作,都得考虑并发。
避坑指南:我曾经在子线程里直接更新UI,结果App闪退了。鸿蒙跟Android一样,UI操作必须在主线程进行。子线程更新UI?想都别想。
1.4 鸿蒙并发编程的核心原则
聊了这么多,我总结几条核心原则,你记一下:
- 能不共享就不共享——数据竞争是并发编程的头号杀手
- 能用TaskPool就别自己造轮子——系统帮你优化好了线程管理
- 主线程永远别做耗时操作——超过16ms用户就能感觉到卡顿
- 锁能不用就不用——锁用多了,并发就变成串行了
- 测试要覆盖并发场景——很多bug只在特定时序下才出现
我记得有一次,一个同事写了个并发下载功能,没加锁就操作共享队列。结果10次测试里,有3次数据错乱。排查了两天才发现是竞态条件。从那以后,我写并发代码都会先画个时序图,把线程间的交互理清楚再动手。
1.5 小结
这一章我们聊了进程和线程的区别,了解了鸿蒙的三种并发模型,也看了几个实际的应用场景。说白了,并发编程就是让多个任务同时干活,但别打架。
下一章,我会带你深入TaskPool,看看怎么用它写出高性能的并发代码。到时候我会分享一些我在项目中踩过的坑,保证让你少走弯路。
一句话总结:进程是地盘,线程是干活的人。鸿蒙给了你TaskPool和Worker两把好用的工具,别用错了地方。