多线程并发模型:Actor模型在ArkTS中的应用(172)

发布时间:2026/10/30 21:20:44

多线程并发模型:Actor模型在ArkTS中的应用(172) 在 ArkTS 中多线程并发编程彻底摒弃了传统基于“共享内存”的模型全面采用了基于消息传递的Actor 并发模型。这种设计从底层架构上避免了复杂的锁竞争与数据竞争问题。以下是 Actor 模型在 ArkTS 中的核心原理、通信机制及两大并发能力的应用一、 核心原理内存隔离与消息传递在 Actor 模型下每一个线程Actor都是一个独立的计算单元拥有自己独占的内存空间、虚拟机实例和事件轮询机制EventLoop。内存隔离线程之间绝对不直接访问对方的内存空间从根本上消除了内存抢占和脏读脏写问题开发者无需处理复杂的锁机制。消息通信Actor 之间通过发送和接收消息来触发彼此的行为。这种异步的消息传递机制保证了高并发下的系统稳定性。二、 线程间通信机制数据传输对象由于内存隔离跨线程的数据交换必须经过序列化或特定的共享机制。ArkTS 支持以下四种数据传输对象普通对象采用标准的结构化克隆算法Structured Clone进行深拷贝。支持基础类型、Date、Array、Map、Set 等但对象越大序列化耗时越长。可转移对象Transferable如ArrayBuffer。采用地址转移机制不进行内容拷贝。转移后原线程中的对象将不可用所有权完全移交。可共享对象SharedArrayBuffer支持多线程间真正的内存共享。由于多线程可能同时修改必须通过Atomics原子操作来保证数据的同步性与安全性。Native 绑定对象如Context和RemoteObject支持序列化传输用于跨线程访问底层系统功能或实现跨进程通信。三、 ArkTS 的两大并发能力基于 Actor 模型ArkTS 提供了TaskPool和Worker两种并发 API适用于不同的业务场景1. TaskPool任务池特点由系统统一管理和调度线程开发者无需手动创建和销毁线程有效避免了线程泛滥。适用场景适合执行相互独立、执行周期短、无上下文依赖的耗时任务。例如JSON 解析、图片/视频编解码、压缩/解压缩、数据库操作等。开发规范任务函数必须使用Concurrent装饰器修饰且只能依赖模块化导入或参数传入不能依赖外部上下文。import { taskpool } from kit.ArkTS; // 【开发规范】任务函数必须是模块顶层函数且使用 Concurrent 装饰器 Concurrent function heavyCalculation(max: number): number { let count 0; for (let i 2; i max; i) { let isPrime true; for (let j 2; j * j i; j) { if (i % j 0) { isPrime false; break; } } if (isPrime) count; } return count; } Entry Component struct TaskPoolDemo { State resultText: string 点击按钮开始计算; build() { Column({ space: 20 }) { Text(this.resultText).fontSize(18) Button(计算 1~200000 的质数) .onClick(async () { this.resultText 计算中...; // 创建任务并派发至 TaskPool const task new taskpool.Task(heavyCalculation, 200000); try { // 异步等待结果不阻塞主线程 const count await taskpool.execute(task) as number; this.resultText 计算完成共有 ${count} 个质数; } catch (e) { this.resultText 执行失败: ${JSON.stringify(e)}; } }) } .width(100%).height(100%).justifyContent(FlexAlign.Center) } }2. Worker工作线程特点开发者手动创建的独立常驻线程拥有完整的运行环境。线程不会主动销毁需要开发者自行管理生命周期。适用场景适合执行有关联性、需要长时间运行大于3分钟或依赖特定句柄/类对象调度的常驻任务。例如游戏业务的主逻辑线程、产线硬件阻塞式压测等。场景创建一个后台常驻线程主线程发送指令启动任务Worker 线程周期性地向主线程回传状态数据。第一步创建 Worker 线程文件 (workers/BackgroundWorker.ets)import { worker, ThreadWorkerGlobalScope, MessageEvents } from kit.ArkTS; const workerPort: ThreadWorkerGlobalScope worker.workerPort; let isRunning: boolean false; // 接收主线程的消息 workerPort.onmessage (e: MessageEvents) { const msg e.data as string; if (msg start) { isRunning true; performTask(); } else if (msg stop) { isRunning false; workerPort.postMessage(Worker 已停止任务); } }; // 模拟长驻任务并持续回传数据 function performTask() { if (isRunning) { workerPort.postMessage(当前时间戳: ${Date.now()}); setTimeout(performTask, 1000); // 每秒执行一次 } }第二步在主线程中管理 Worker 生命周期 (Index.ets)import { worker, MessageEvents } from kit.ArkTS; Entry Component struct WorkerDemo { State statusText: string Worker 未启动; private workerInstance: worker.ThreadWorker | null null; build() { Column({ space: 20 }) { Text(this.statusText).fontSize(18) Button(启动 Worker) .onClick(() { if (!this.workerInstance) { // 创建 Worker 实例 this.workerInstance new worker.ThreadWorker(entry/ets/workers/BackgroundWorker.ets); // 监听 Worker 回传的消息 this.workerInstance.onmessage (e: MessageEvents) { this.statusText e.data as string; }; } this.workerInstance.postMessage(start); }) Button(停止 Worker) .onClick(() { this.workerInstance?.postMessage(stop); }) } .width(100%).height(100%).justifyContent(FlexAlign.Center) } // 页面销毁时务必终止 Worker防止内存泄漏 aboutToDisappear() { this.workerInstance?.terminate(); this.workerInstance null; } }3. TaskPool 中的持续通信sendData / onReceiveData场景如果不想使用 Worker但 TaskPool 任务在执行过程中需要向主线程发送中间进度数据。import { taskpool } from kit.ArkTS; Concurrent function taskWithProgress(total: number): string { for (let i 0; i total; i) { // 通过 sendData 向主线程发送中间状态 taskpool.Task.sendData(i); } return 任务全部完成; } // 在主线程中监听进度 const task new taskpool.Task(taskWithProgress, 100); task.onReceiveData((progress: number) { console.info(当前进度: ${progress}%); }); const finalResult await taskpool.execute(task) as string; console.info(finalResult);4. 进阶通信机制ArrayBuffer 的零拷贝转移与共享在跨线程传输大量二进制数据如图片像素、音频流时默认的深拷贝Structured Clone会带来极大的性能损耗。ArkTS 提供了零拷贝的传输方案。实战代码使用 Transfer 机制转移 ArrayBuffer 所有权import { taskpool } from kit.ArkTS; Concurrent function processImageBuffer(buffer: ArrayBuffer): ArrayBuffer { // 在子线程中直接处理二进制数据无需深拷贝 const view new Uint8Array(buffer); view[0] 255; // 修改数据 return buffer; } async function transferDemo() { const buffer new ArrayBuffer(1024 * 1024); // 1MB 数据 // 将 buffer 作为 Transfer 对象传递 const task new taskpool.Task(processImageBuffer, buffer); // 关键设置转移列表传递后主线程中的 buffer 将被置为不可用Neutered task.setTransferList([buffer]); await taskpool.execute(task); // console.log(buffer.byteLength); // 此时访问会报错所有权已转移 }5. 进阶通信机制SharedArrayBuffer 与 Atomics 无锁并发当多个线程需要高频读写同一块内存如共享状态计数器、自旋锁时使用 SharedArrayBuffer 配合 Atomics 实现真正的内存共享。实战代码子线程安全的原子计数器import { taskpool } from kit.ArkTS; Concurrent function atomicCounter(sharedBuffer: SharedArrayBuffer): void { const int32 new Int32Array(sharedBuffer); for (let i 0; i 1000; i) { // 原子加法绝对安全不会发生数据竞争 Atomics.add(int32, 0, 1); } } async function sharedMemoryDemo() { const sab new SharedArrayBuffer(4); const int32 new Int32Array(sab); // 并发派发 10 个任务 const group new taskpool.TaskGroup(); for (let i 0; i 10; i) { group.addTask(new taskpool.Task(atomicCounter, sab)); } await taskpool.execute(group); console.info(最终计数: ${Atomics.load(int32, 0)}); // 预期结果严格为 10000 }6. 任务编排TaskGroup 与任务依赖管理在实际业务中任务往往不是孤立的。TaskPool 提供了强大的任务编排能力支持任务组批量执行和树状依赖。实战代码并行加载资源全部完成后触发渲染import { taskpool } from kit.ArkTS; Concurrent function loadTexture(id: number): string { return Texture_${id}_Loaded; } Concurrent function loadModel(id: number): string { return Model_${id}_Loaded; } async function orchestrationDemo() { const group new taskpool.TaskGroup(); // 添加多个并行任务 group.addTask(new taskpool.Task(loadTexture, 1)); group.addTask(new taskpool.Task(loadTexture, 2)); group.addTask(new taskpool.Task(loadModel, 1)); // 等待组内所有任务执行完毕统一返回结果数组 const results await taskpool.execute(group) as string[]; console.info(所有资源加载完成:, results); }7. 任务调度优先级控制与防饥饿机制为了防止高负载下低优先级任务被饿死TaskPool 提供了优先级调度机制底层对接了系统的 QoSQuality of Service。实战代码区分 UI 响应任务与后台备份任务import { taskpool } from kit.ArkTS; Concurrent function uiResponsiveTask(): string { return UI 刷新数据; } Concurrent function backgroundBackupTask(): string { return 后台数据备份; } async function priorityDemo() { // 高优先级立即调度保障 UI 流畅 const highTask new taskpool.Task(uiResponsiveTask); highTask.setPriority(taskpool.Priority.HIGH); // 空闲优先级仅在所有线程空闲时执行不抢占资源 const idleTask new taskpool.Task(backgroundBackupTask); idleTask.setPriority(taskpool.Priority.IDLE); taskpool.execute(highTask); taskpool.execute(idleTask); }8. 跨线程状态共享Sendable 装饰器与对象传递从 API version 11 开始若需要在跨并发实例传递带方法的实例对象该类必须使用Sendable装饰器标注以告知编译器该对象是线程安全的。实战代码跨线程传递自定义业务对象import { taskpool, Sendable } from kit.ArkTS; // 标记为 Sendable允许跨线程传递 Sendable class UserInfo { name: string; age: number; constructor(name: string, age: number) { this.name name; this.age age; } } Concurrent function processUser(user: UserInfo): string { return 处理用户: ${user.name}, 年龄: ${user.age}; } async function sendableDemo() { const user new UserInfo(Alice, 25); const task new taskpool.Task(processUser, user); const result await taskpool.execute(task) as string; console.info(result); }
延伸阅读

更多相关文章

2026/10/29 1:06:17

N皇后问题的遗传算法实战:Python向量化实现与fitness设计

1. 这不是教科书里的遗传算法,而是我亲手调通100皇后问题后写下的实操手记你点开这篇文章,大概率不是为了背诵“遗传算法是模拟生物进化过程的优化方法”这种定义。你真正想搞明白的是:当代码跑起来之后,为什么它有时卡在600分不动…

2026/10/28 18:34:49

分库分表的中间件实现(简化版)

一、 系统上线两年,用户数据从 GB 涨到 TB,查询从毫秒级退化到秒级。分库分表、读写分离、索引优化都做了,但性能瓶颈依然明显。这时候才意识到,关系型数据库不是万能的,某些场景需要引入 NoSQL 或 NewSQL。数据库选型…

2026/10/30 21:16:32

如何迁移 pi-extensions 弃用包:deprecated 扩展升级指南

【免费下载链接】pi-extensions A monorepo of Pi Coding Agent extensions 项目地址: https://gitcode.com/gh_mirrors/pi/pi-extensions 点击查看 免费下载 如果你在使用 Pi Coding Agent 扩展仓库 pi-extensions,会发现部分扩展已被移入 deprecated/…

2026/10/30 21:16:32

【保姆级打包】如何3分钟给Qt Designer装上简体中文语言包

【保姆级打包】如何3分钟给Qt Designer装上简体中文语言包 【免费下载链接】QtDesigner简体中文语言包 本仓库提供了一个用于 Qt Designer 的简体中文语言包文件:designer_zh_CN.qm。通过使用该语言包,您可以将 Qt Designer 的用户界面语言切换为简体中文…

2026/10/30 21:11:31

QCOM_V1.6深度解析:面向通信模组的协议级串口调试工作流

1. 这不是“下载链接”,而是一套被低估的串口调试工作流很多人看到“QCOM_V1.6安装包免费下载”这个标题,第一反应是点开找网盘链接、复制提取码、解压双击运行——然后发现界面卡顿、AT指令无响应、日志刷屏却找不到关键报错,最后默默卸载&a…

2026/10/30 21:11:31

STM32智慧仓库管理系统:从传感器到上位机的完整实现

简介:一份基于STM32的智慧仓库管理系统完整毕业设计源码包,面向正在准备毕设的计算机相关专业学生及需要项目实战的C语言学习者,也可直接用作课程设计或期末大作业。资源共403个文件,压缩包约15.47MB,核心代码以C语言源…

2026/10/30 21:11:31

Unity数字孪生机械臂控制:虚实联动通信层搭建与避坑指南

简介:这套资源围绕数字孪生、Unity与机械臂控制的虚实联动项目,面向Unity开发者、工业数字孪生学习者及自动化控制爱好者,帮助解决虚拟环境与真实机械臂之间双向通信与同步控制的落地问题。资源中涉及三维场景搭建、机械臂模型处理、滑动条UI…

2026/10/30 20:55:10

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/30 20:55:10

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/30 20:55:09

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/30 0:00:46

NCP1342高频准谐振反激控制器:从设计约束到验收的完整方案

简介:NCP1342 高频准谐振反激控制器应用介绍译文文档,面向电源设计工程师、硬件研发人员及开关电源学习者,帮助读者跨越英文原版资料的语言门槛,系统理解这款高集成度 QR Flyback 控制器的设计要点。文档围绕芯片核心特性展开&…

2026/10/30 0:00:46

NCP1342准谐振反激电源设计:从选型到验收的全流程解析

简介:这份文档面向电源设计工程师与开关电源学习者,系统梳理NCP1342高频准谐振反激控制器的应用要点,帮助读者快速理解这款高集成度离线电源变换器控制芯片的工作机制与设计方法。内容涵盖芯片核心特性、引脚功能定义、电气特性参数表、最大额…

2026/10/30 0:00:46

Web系统自动登出机制设计与实现全解析

1. 系统自动登出机制的设计初衷在各类Web应用和后台管理系统中,自动登出功能早已成为标配。这个看似简单的功能背后,实际上涉及用户安全、资源管理和体验优化的多重考量。作为从业十多年的老开发,我见过太多因为登出逻辑设计不当导致的安全事…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑