[鸿蒙从零到一] ArkTS Sendable 数据模型与跨线程共享实战

简介: Sendable 是 ArkTS 实现跨线程零拷贝共享的核心机制:通过编译期类型校验与 Shared Heap 运行时支持,使对象真正被多线程共用。需显式标注、字段限于基础类型或 Sendable 容器(如 collections.Map),并发写操作须配合 AsyncLock 保障一致性。适用于大数据只读或可变状态共享场景,小数据仍推荐结构化克隆。

为什么需要 Sendable

ArkTS 的多线程模型(taskpool、Worker)不像 JVM 那样共享堆内存。跨线程默认走结构化克隆(structured clone),代价是拷贝开销 + 引用断裂:主线程改了一份,子线程看不到。业务里但凡涉及大列表、缓存、状态机在多线程之间流动,克隆语义就成了性能与一致性的双重瓶颈。
Sendable 数据模型的定位就是让一份对象真正跨线程共享,而不是每次传递都深拷贝。它是 ArkTS 静态类型系统 + 运行时并发原语共同支撑出来的机制,本质上把"可跨线程"变成了一种编译期能校验的对象契约。

原理:Sendable 到底做了什么

Sendable 对象在运行时被分配到一个跨线程可访问的堆区域(Shared Heap)。它的字段类型受限,只能是:

  • 基础类型(number / string / boolean / bigint / null / undefined)
  • 其他 Sendable 类实例
  • Sendable 容器:collections.Array、collections.Map、collections.Set 等

关键约束有三条:

  • 字段必须显式声明类型,不允许 any / unknown / 联合含非 Sendable 类型。
  • 方法内不能捕获非 Sendable 的外部变量(闭包被静态检查器拒绝)。
  • 并发访问不是自动加锁,共享 = 可见性;一致性需要开发者自己用 ArkTSUtils.locks.AsyncLock 或 CAS 语义保证。

这三条决定了 Sendable 是"零拷贝但有代价"的模型:省下克隆开销,换来对并发正确性的显式管理。

最小可运行示例:跨线程共享一个计数器

`// shared_counter.ets
import { taskpool } from '@kit.ArkTS';
import { collections } from '@kit.ArkTS';
import { ArkTSUtils } from '@kit.ArkTS';

@Sendable
export class SharedCounter {
private value: number = 0;
private lock: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();

async increment(): Promise<number> {
return this.lock.lockAsync(() => {
this.value += 1;
return this.value;
});
}

get(): number {
return this.value;
}
}

@Concurrent
async function bump(counter: SharedCounter, times: number): Promise<number> {
let last = 0;
for (let i = 0; i < times; i++) {
last = await counter.increment();
}
return last;
}

export async function runDemo(): Promise<number> {
const counter = new SharedCounter();
const tasks: Promise<number>[] = [];
for (let i = 0; i < 4; i++) {
tasks.push(taskpool.execute(bump, counter, 1000) as Promise<number>);
}
await Promise.all(tasks);
return counter.get(); // 期望 4000
}
这里的重点:counter只 new 了一次,四个 taskpool 任务拿到的是同一个实例的引用。如果去掉@Sendable,运行时会报"参数不可跨线程";如果去掉AsyncLock,四个 worker 竞争value += 1` 会拿到少于 4000 的结果——共享内存意味着竞态可复现,这一点比 structured clone 时代更需要谨慎。

Sendable 容器 vs 普通数组

常规 Array&lt;T&gt; 不是 Sendable,扔进 taskpool 只能触发克隆。真正做到共享要用 @kit.ArkTS 的 collections 命名空间:
`import { collections } from '@kit.ArkTS';

@Sendable
export class HotCache {
data: collections.Map<string, string> = new collections.Map();
put(k: string, v: string): void { this.data.set(k, v); }
get(k: string): string | undefined { return this.data.get(k); }
}
差异在于collections.Map底层实现了跨线程内存屏障与迭代安全;Map/ 普通Array只在当前 VM 隔离区可见。混用最常见的坑是:把普通Array塞到@Sendable` 类的字段里,编译器直接拒绝;而在方法内部临时构造普通数组再返回,则会在返回值路径上触发克隆,抵消了共享的意义。

性能对比:克隆 vs 共享

用一个 10 万条记录的列表做基准(DevEco Profiler 采样,Mate 60 Pro,冷启动后稳定态平均值):

方案主线程传递耗时子线程读耗时峰值内存

普通 Array<Record> + taskpool~180ms(结构化克隆)~4ms2× 数据大小
@Sendable + collections.Array<1ms(引用传递)~5ms(首次跨线程访问轻微开销)1× 数据大小

结论清晰:数据越大,Sendable 的收益越接近线性放大;小对象反而看不出差别,此时用 structured clone 更简单。选型的分界线一般在"单次传递 > 1 万条 / 1MB"这个量级。

常见踩坑清单

  • 忘记标 @Sendable:类字段互相引用时,只要有一个漏标,编译器就会把整棵引用图判为不可跨线程。
  • 字段用了普通 Array/Map:换成 collections.*,否则运行时抛 BusinessError 10200201。
  • 方法内捕获 UI 状态:@State、AppStorage 都不是 Sendable,禁止在 Sendable 类的方法里直接访问;应在主线程侧读出快照再传参。
  • 忽略锁:Sendable = 共享内存,不 = 自动同步;写操作必须走 AsyncLock 或原子容器。
  • 把 Sendable 对象持久化:Preferences / relationalStore 不识别 Sendable 元数据,落盘前要转成 POJO 或 JSON。

方法论:什么时候该用 Sendable

把跨线程数据流分成三类,选型就清晰了:

  • 一次性任务参数(< 100KB,用完即抛):直接 structured clone,代码最简单。
  • 大批量只读数据(列表、字典、模型输入):Sendable + collections,省克隆开销。
  • 可变共享状态(缓存、计数器、状态机):Sendable + AsyncLock,把并发正确性显式化到代码里。

不要把 Sendable 当成"高性能默认选项"。它引入的心智负担是真实的:一旦对象跨线程共享,任何写操作都要重新审视竞态。工程上更好的做法是——先用 structured clone 跑通业务,等 Profiler 指认克隆成为瓶颈时再迁移到 Sendable。

小结

Sendable 是 ArkTS 并发模型从"消息传递"走向"共享内存"的关键一步。它借助严格类型系统把可共享性做成了编译期契约,用 collections 容器把跨线程内存屏障做成了运行时能力,用 AsyncLock 把同步义务显式化。理解它的三条约束、掌握它的性能边界、遵守它的锁纪律,才能让多线程代码在鸿蒙上真正跑出该有的速度。

相关文章
|
2月前
|
人工智能 JavaScript 测试技术
从0到1搭建AI辅助测试环境:2026最新版,建议收藏
告别繁琐配置!30分钟用Node.js+DeepSeek Harness+Playwright搭好AI测试环境,无需Python、不配服务器,API Key一贴即用。支持AI自动生成/执行Web测试用例,新手也能零门槛上手——最难的不是技术,是“以为很难”的念头。
|
2月前
|
运维 自然语言处理 安全
企业终端精细化管理实践:从策略配置到运维效率提升
本文基于企业级终端安全管理平台的实际策略配置能力,从客户端权限管控、资产信息管理、实时沟通协作、运维工具箱、登录安全与多语言适配五个维度,分享终端精细化管理的落地实践,探讨如何在安全与效率之间找到平衡。
企业终端精细化管理实践:从策略配置到运维效率提升
|
2月前
|
人工智能 缓存 API
Codex接入DeepSeek‑V4‑Flash实操指南:两套方案补齐识图能力完整保姆级教程
在AI编程Agent工具生态之中,Codex凭借强大的本地工程读写、代码修改、终端命令执行能力,成为开发者做项目调试、代码重构、问题定位的高频客户端。DeepSeek‑V4‑Flash作为一款高性价比文本大模型,拥有百万级超大上下文窗口,在Agent任务规划、代码生成、复杂逻辑推演场景表现突出,API调用成本低廉,非常适合作为Codex底层推理基座。但该模型属于纯文本推理模型,原生并不支持图像输入,当开发者把报错截图、UI界面截图、架构示意图、数据图表粘贴进会话,模型会直接提示无法解析图片内容,大量开发场景直接被阻断。
441 3
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
从 AI Agent 到脑机接口:人工智能下一阶段的感知、认知与人机融合
本文中关于当前 AI、AI Agent、脑机接口和神经信号解码的部分,基于公开技术研究进行概括;关于“人机认知融合”“AI是否可能拥有思想”等内容属于作者个人技术推演,不代表现阶段已经实现的技术。 目前 BCI 研究已经形成“神经信号采集—解码—反馈/执行”的基本技术框架,并已经在辅助通信、运动控制等方向产生实际研究成果;但从特定神经信号解码发展到完整、稳定、长期的人类思想或意识读取,仍存在巨大的技术和科学距离
|
2月前
|
存储 运维 监控
阿里云香港轻量应用服务器最新配置价格及实测测评,建站选购避坑完整指南
对于想要搭建面向海外访问站点、开发测试项目,不想做备案流程的开发者、个人站长以及小微企业来说,香港地域的云主机是十分热门的选择。阿里云香港轻量应用服务器作为主打开箱即用的跨境计算产品,凭借套餐打包模式、简单的运维操作、独立公网IP,成为很多跨境项目的首选。但跨境服务器和内地节点产品存在大量差异化规则,网络线路、流量计费、性能上限、产品限制都和内地轻量实例不一样,如果只看低廉的售价盲目下单,后续很容易遇到网络波动、账单异常、业务无法扩容等各类问题。本文结合最新在售套餐配置、实际性能测评数据,搭配实操命令,完整拆解这款产品的价格体系、硬件性能、网络表现、适用边界以及大量实战踩坑点,帮助大家判断自己
924 2
|
2月前
|
人工智能 自然语言处理 安全
Claude Code 被曝提示注入漏洞,成功率能到 80%——你的 Agent 可能正在"被网页说服"
一份安全测试报告揭示:Claude Code等AI Agent在Auto Mode下易遭网页内容劫持——仅需在普通网页嵌入隐蔽指令,即可误导其偏离原任务,成功率高达60%–80%。问题根源在于模型无法区分“用户指令”与“网页文本”,且权限过高。这非单一产品漏洞,而是所有具备网页读取+执行能力的Agent共性风险。当前最务实的应对,是将Agent视为需审批的“新人”,关键操作人工确认、权限分离、操作留痕、明确高危清单。能力跃进之时,“可信执行”机制才刚起步。
101 1
|
2月前
|
弹性计算 安全 Linux
阿里云服务器安装ZBlog博客全流程,99元上线我的个人博客!
本教程详解如何在阿里云99元ECS服务器(CentOS 7.9)上,通过宝塔Linux面板一键部署Z-BlogPHP博客系统,涵盖远程连接、安装宝塔、开通端口、配置LNMP及Z-Blog部署全流程,操作简单,附代金券领取入口。阿里云服务器ECS官网:https://t.aliyun.com/U/AZBUsA
266 1
|
2月前
|
存储 移动开发 小程序
代练平台搭建/代练护航三角洲小程序开发/源码成品系统部署教程
涵盖用户端(下单、担保支付、进度追踪、IM沟通)、打手端(实名认证、接单履约)及管理后台(订单仲裁、财务结算、内容配置)。采用UniApp+ThinkPHP多端架构,支持小程序/H5/APP,具备ICP备案、数据加密与日志留存等合规能力。
232 1
|
2月前
|
供应链 前端开发 BI
数据指标体系怎么搭?终于有人一次讲清楚了
企业常陷“指标多、分析难、行动少”困局,根源在于仅有零散“指标清单”,缺乏围绕经营目标构建的完整指标体系。真正有效的体系需贯通“目标—指标—维度—数据—责任—行动”,实现可下钻、可归因、可执行。(239字)
|
2月前
|
缓存 人工智能 前端开发
阿里云qwen3.6-max-preview模型详解:模型能力、价格、上下文限制及使用注意事项参考
本文介绍了阿里云通义千问Qwen3.6系列中综合能力最强的预览版大模型qwen3.6-max-preview,该纯文本模型在Vibe Coding体验、Coding Agent执行效率与前端编程能力上实现显著升级,同时大幅拓展了长尾专业知识覆盖范围。它默认开启混合深度思考模式,支持262k超长上下文,在北京与新加坡双区域部署,适配高阶全栈开发、细分领域专业知识处理、前沿AI应用概念验证等场景。文章同步梳理了分档梯度定价策略与API调用要点,明确提示该预览版暂不支持批量推理与模型调优,更适合用于技术预研与编程智能体验测试,新用户登录百炼平台即可领取百万Tokens免费试用额度。