本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、Sendable 对象
1. 背景
-
传统问题:JS引擎中对象并发通信开销大,需通过Native侧Transferable对象优化。
-
ArkTS解决方案:提供Sendable对象类型,支持并发通信时通过引用传递降低开销。
-
核心特性:Sendable对象可跨线程共享,指向同一个JS对象,避免拷贝开销。
2. 通信机制
-
引用传递:默认采用引用传递方式跨线程共享。
-
线程安全:如包含Native实现,需确保线程安全性。
-
数据竞争防护:提供异步锁、异步等待、对象冻结等机制防止数据竞争。
二、Sendable 结构
1. Sendable协议
-
定义了ArkTS可共享对象体系及其规格约束。
-
符合协议的数据可在ArkTS并发实例间传递。
2. ISendable接口
-
位于
@arkts.lang基础库中,无方法或属性。 -
是所有Sendable类型(除null和undefined)的父类型。
-
@Sendable装饰器是implement ISendable的语法糖。
3. Sendable类型分类
-
Sendable class:使用
@Sendable装饰器标注的类。 -
Sendable function:使用
@Sendable装饰器标注的函数。 -
Sendable interface:继承ISendable的接口。
三、Sendable 支持的数据类型
1. 基础类型
-
boolean、number、string、bigint、null、undefined
-
const enum(常量枚举)
2. 标准库类型
-
容器类型:需显式引入
@arkts.collections -
异步锁对象:需显式引入
@arkts.utils -
异步等待对象:需显式引入
@arkts.utils -
SendableLruCache对象:需显式引入
@arkts.utils
3. 系统对象
-
共享用户首选项
-
基于Sendable对象的图片处理、资源管理
-
SendableContext对象管理
4. 其他类型
-
元素均为Sendable类型的union type数据
-
自定义的Native Sendable对象
-
标注了
@Sendable装饰器的class和function
5. 不支持的类型
-
JS内置对象:遵循结构化克隆算法,拷贝传递
-
对象字面量和数组字面量:拷贝传递,非Sendable类型
四、Sendable 实现原理
1. 内存模型
-
共享堆(SharedHeap):进程级别堆空间,所有线程可访问
-
本地堆(LocalHeap):单个并发实例访问,线程隔离
-
Sendable对象分配在SharedHeap中,实现跨线程内存共享
2. 生命周期管理
-
Sendable对象存活取决于所有并发实例是否存在对其的引用
-
SharedHeap不能引用LocalHeap中的对象
五、@Sendable 装饰器
1. 基本规范
| 项目 | 规范说明 |
|---|---|
| 装饰器参数 | 无 |
| 使用场景 | 仅Stage模型的.ets文件 |
| 函数类型 | 普通function、Async function |
| 类继承 | Sendable class只能继承Sendable class |
2. 属性类型限制
-
支持:string、number、boolean、bigint、null、undefined、Sendable class、collections容器集、异步锁、SendableLruCache等
-
禁止:使用闭包变量(顶层定义除外)
-
不支持:通过
#定义私有属性(需用private)、计算属性
3. 其他限制
-
成员属性必须显式初始化,不能使用感叹号
-
不支持增加或删除属性,允许修改属性(类型必须一致)
-
不支持修改方法
-
从API 18开始支持访问本文件导出的变量
4. 适用场景
-
在TaskPool或Worker中使用类方法或Sendable函数
-
传输大数据量对象:传输100KB数据效率提升约20倍,1MB数据提升约100倍
六、使用示例
1. Sendable 类
@Sendable
class DataModel {
status: ModelStatus = ModelStatus.ACTIVE;
data: string = "initial data";
updateStatus(newStatus: ModelStatus): void {
this.status = newStatus;
}
displayInfo(): void {
console.info(`Model status: ${this.status}, data: ${this.data}`);
}
}
@Concurrent
function processModel(model: DataModel): void {
model.updateStatus(ModelStatus.PROCESSING);
model.displayInfo();
}
2. Sendable 方法
// 定义Sendable函数类型
@Sendable
type DataProcessor = (input: string) => string;
@Sendable
class ProcessingService {
processor: DataProcessor;
constructor(processor: DataProcessor) {
this.processor = processor;
}
executeProcessing(input: string): string {
return this.processor(input);
}
}
@Sendable
function textTransform(input: string): string {
return input.toUpperCase() + "_PROCESSED";
}
// 使用示例
const service = new ProcessingService(textTransform);
const result = service.executeProcessing("hello world");
console.info(`Processing result: ${result}`);
七、优势
-
大幅提升传输效率
-
避免了序列化/反序列化的性能开销
-
特别适合大对象跨线程通信场景
八、线程安全方面
-
使用异步锁(AsyncLock)避免数据竞争
-
使用异步等待(ConditionVariable)控制多线程时序
-
通过对象冻结接口将对象设为只读,避免并发修改
1078

被折叠的 条评论
为什么被折叠?



