鸿蒙开发手册HARMONYOS

CHAPTER 02并发模型 · CONCURRENCY

并发模型

主线程(UI)必须流畅。鸿蒙提供 TaskPool(任务池)与 Worker(线程)两种并发手段,配合 Promise/async 处理异步任务。

开始阅读难度进阶约3小时
02.1

为什么需要并发

UI 线程负责渲染与交互,耗时任务(解码、计算、网络)必须离开主线程,否则掉帧卡顿。

两类手段

TaskPool 适合大量短任务(自动调度、轻量);Worker 适合长驻或需持续通信的任务(独立线程)。

02.2

Promise 与 async

异步 API 返回 Promise,用 async/await 写成同步风格,避免回调嵌套。

async function load(): Promise<string> {
  const data = await fetchSomething()
  return data
}
// 并行
const [a, b] = await Promise.all([loadA(), loadB()])
02.3

TaskPool

用 taskpool.execute 把纯函数派发到任务池执行,自动管理线程。

import taskpool from '@ohos.taskpool'
function compute(n: number): number { return n * n }
const task = new taskpool.Task(compute, 10)
taskpool.execute(task).then((r) => console.info(r))
Task 需可序列化

TaskPool 跨线程传递参数,入参与返回值需可序列化,闭包捕获也受限制。

02.4

Worker

Worker 是独立线程,通过 postMessage/onmessage 与宿主通信,适合长驻任务。

// main
const worker = new worker.ThreadWorker("entry/ets/workers/myworker.ts")
worker.postMessage({ cmd: "start" })
worker.onmessage = (e) => console.info(e.data)
// worker.ts
workerPort.onmessage = (e) => workerPort.postMessage("done")
02.5

任务取消

长时间任务应支持取消,避免资源浪费。TaskPool 任务可持有句柄取消;Worker 用消息通知退出。

const task = new taskpool.Task(compute, 10)
const res = taskpool.execute(task)
task.cancel()   // 请求取消
02.6

线程安全

跨线程共享状态需谨慎,优先通过消息传递(而非共享内存)交换数据,避免竞态。

02.7

与 UI 协作

并发结果回到主线程后更新 @State,由 ArkUI 自动刷新。

@State result: string = ""
aboutToAppear() {
  taskpool.execute(new taskpool.Task(fetchText))
    .then((r) => this.result = r as string)
}
02.8

常见陷阱

为什么 Task 里访问 this 报错了?

TaskPool 任务在另一线程执行,无法访问 UI 组件实例。把所需数据作为参数传入,结果回传主线程再更新状态。

Worker 一直不退出会怎样?

Worker 是常驻线程,不主动 terminate 会持续占用资源。任务结束后调用 worker.terminate() 释放。

02.9

实战练习

延伸资源