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 鸿蒙并发编程的核心原则

聊了这么多,我总结几条核心原则,你记一下:

  1. 能不共享就不共享——数据竞争是并发编程的头号杀手
  2. 能用TaskPool就别自己造轮子——系统帮你优化好了线程管理
  3. 主线程永远别做耗时操作——超过16ms用户就能感觉到卡顿
  4. 锁能不用就不用——锁用多了,并发就变成串行了
  5. 测试要覆盖并发场景——很多bug只在特定时序下才出现

我记得有一次,一个同事写了个并发下载功能,没加锁就操作共享队列。结果10次测试里,有3次数据错乱。排查了两天才发现是竞态条件。从那以后,我写并发代码都会先画个时序图,把线程间的交互理清楚再动手。

1.5 小结

这一章我们聊了进程和线程的区别,了解了鸿蒙的三种并发模型,也看了几个实际的应用场景。说白了,并发编程就是让多个任务同时干活,但别打架

下一章,我会带你深入TaskPool,看看怎么用它写出高性能的并发代码。到时候我会分享一些我在项目中踩过的坑,保证让你少走弯路。

一句话总结:进程是地盘,线程是干活的人。鸿蒙给了你TaskPool和Worker两把好用的工具,别用错了地方。