鸿蒙 NEXT 开发中,普通对象跨线程如何传递
1.35个Redis企业级性能优化点与解决方案2.对比传统数据库,TiDB 强在哪?谈谈 TiDB 的适应场景和产品能力3.深度长文解析SpringWebFlux响应式框架15个核心组件源码4.Nginx性能调优5招35式不可不知的策略实战5.Java Executors类的9种创建线程池的方法及应用场景分析6.Redis数据结构—跳跃表 skiplist 实现源码分析7.Volatile不保证原子性及解决方案8.吃透 JVM 诊断方法与工具使用9.Java RMI技术详解与案例分析10.通过JUnit源码分析学习编程的奇技淫巧11.什么是依赖倒置原则12.初探 Rust 语言与环境搭建13.为什么用Vite框架?来看它的核心组件案例详解14.Vue状态管理库Pinia详解15.Tomcat的配置文件中有哪些关键的配置项,它们分别有什么作用?16.ECharts实现雷达图详解17.OpenFeign深入学习笔记18.阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略19.除了递归算法,要如何优化实现文件搜索功能20.关于建表字段是否该使用not null这个问题你怎么看?21.三大硬核方式揭秘:Java如何与底层硬件和工业设备轻松通信!22.在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?23.10款好用的开源 HarmonyOS 工具库24.尝鲜 HarmonyOS NEXT 开发环境搭建25.HarmonyOS NEXT 底部选项卡功能26.HarmonyOS NEXT 开发之ArkTS基础入门27.ArkTS 和仓颉的特性对比与案例28.Spark任务OOM问题如何解决?29.鸿蒙NEXT开发声明式UI是咋回事?30.HarmonyOS NEXT开发之ArkTS自定义组件学习笔记31.如何在鸿蒙 NEXT 中使用 @Builder 装饰器优化 UI 组件的复用?32.鸿蒙 NEXT 如何使用 @Styles 装饰器来优化我的组件代码?33.Java 如何确保 JS 不被缓存34.10月22日纯血鸿蒙正式版发布意味着什么?35.鸿蒙NEXT应用上架与分发步骤详解36.Java EasyExcel 导出报内存溢出如何解决37.Java Z 垃圾收集器如何彻底改变内存管理38.聊聊公众号联动扫码登录功能如何实现39.IDEA中通义灵码的使用技巧40.细谈 Linux 中的多路复用epoll41.适合才最美:Shiro安全框架使用心得42.MongoDB面试专题33道解析43.SQL Server 数据太多如何优化44.【项目场景】请求数据时测试环境比生产环境多花了1秒是怎么回事?45.Java灵魂拷问13个为什么,你都会哪些?46.异步编程在ArkTS中具体怎么实现?47.如何理解ArkTS不支持structural typing48.ArkTS四种渲染控制能力49.在ArkTS中,如何优化布局以提高性能?50.ArkUI与MVVM模式的诗和远方51.鸿蒙NEXT开发中如何确保使用 PersistentStorage 存储的数据安全?52.优雅的@ObservedV2和@Trace装饰器53.10个案例告诉你mysql不使用子查询的原因54.鸿蒙 NEXT 开发中,使用公共事件进行进程间通信55.鸿蒙NEXT开发中使用星闪服务56.鸿蒙NEXT使用request模块实现本地文件上传57.玩转 DevEco Studio 5 代码重构功能58.JAVA线程池有哪些队列? 以及它们的适用场景案例59.2025 年,程序员如何找准技术“掘金点”?
60.鸿蒙 NEXT 开发中,普通对象跨线程如何传递
61.什么是内存泄漏?C++中如何检测和解决?62.使用贪心算法解决最小生成树问题63.如何使用 Python 进行文件读写操作?64.如何在Python中高效地读写大型文件?65.2025春招,Spring 面试题汇总66.2025春招 SpringCloud 面试题汇总大家好,我是 V 哥,在鸿蒙HarmonyOS NEXT开发中,跨线程对象传递可以通过拷贝形式实现,确保两个线程的对象内容一致,但各自指向线程的隔离内存区间。以下是使用SharedArrayBuffer
实现跨线程共享内存的完整案例代码,包括详细解释,整理的学习笔记,分享给大家。关注威哥不迷路,学习鸿蒙就很酷。
案例代码
1. 主线程代码
@Component
export struct LockUsage {
taskNum: number = 10; // 任务数,实际并行线程数依设备而定
baseDir: string = getContext().filesDir + '/TextDir'; // 文件写入的应用沙箱路径
sabInLock: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主线程,初始化子线程锁标志位,所使用的共享内存
sabForLine: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主线程,初始化子线程偏移位,所使用的共享内存
@State result: string = "";
build() {
Row() {
Column() {
Button($r('app.string.not_use_lock'))
.width("80%").fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 30 })
.onClick(async () => {
this.startWrite(false);
})
Button($r('app.string.use_lock'))
.width("80%")
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 30 })
.onClick(async () => {
this.startWrite(true);
})
Text(this.result)
.width("80%")
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(Color.Blue)
.margin({ top: 30 })
}
.width('100%')
}
.height('100%')
}
startWrite(useLock: boolean): void {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_start'));
let whichLineToWrite: Int32Array = new Int32Array(this.sabForLine);
Atomics.store(whichLineToWrite, 0, 0);
let taskPoolGroup: taskpool.TaskGroup = new taskpool.TaskGroup();
for (let i: number = 0; i < this.taskNum; i++) {
taskPoolGroup.addTask(new taskpool.Task(createWriteTask, this.baseDir, i, this.sabInLock, this.sabForLine, useLock));
}
taskpool.execute(taskPoolGroup).then(() => {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_success'));
}).catch(() => {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_failed'));
})
}
}
2. 子线程代码
@Concurrent
async function createWriteTask(baseDir: string, writeText: number, sabInLock: SharedArrayBuffer, sabForLine: SharedArrayBuffer, useLock: boolean): Promise<void> {
class Option {
offset: number = 0;
length: number = 0;
encoding: string = 'utf-8';
constructor(offset: number, length: number) {
this.offset = offset;
this.length = length;
}
}
let filePath: string | undefined = undefined;
filePath = baseDir + useLock ? "/useLock.txt" : "/unusedLock.txt";
if (!fs.accessSync(baseDir)) {
fs.mkdirSync(baseDir);
}
let nrl: NonReentrantLock | undefined = undefined;
if (useLock) {
nrl = new NonReentrantLock(sabInLock);
}
let whichLineToWrite: Int32Array = new Int32Array(sabForLine);
let str: string = writeText + '\n';
for (let i: number = 0; i < 100; i++) {
if (useLock && nrl !== undefined) {
nrl.lock();
}
let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
try {
fs.writeSync(file.fd, str, new Option(whichLineToWrite[0], str.length));
} catch (err) {
logger.error(`errorCode : ${err.code},errMessage : ${err.message}`);
}
fs.closeSync(file);
whichLineToWrite[0] += str.length;
if (useLock && nrl !== undefined) {
nrl.unlock();
}
}
}
详细解释
-
主线程初始化共享内存:
sabInLock
和sabForLine
是两个SharedArrayBuffer
对象,分别用于子线程锁标志位和偏移位。它们在主线程中被初始化,并将被传递给子线程,实现跨线程共享内存。
-
子线程写入文件:
- 子线程根据主线程传入的
SharedArrayBuffer
初始化锁和偏移量。 - 使用锁确保线程安全,避免多个线程同时写入文件时出现数据竞争。
- 通过
Atomics.store
和Atomics.load
操作共享内存,实现线程间的同步。
- 子线程根据主线程传入的
-
线程间参数传递:
- 使用
taskpool.Task
创建子线程任务,并通过taskpool.execute
执行。 - 子线程任务通过
createWriteTask
函数实现,该函数接收主线程传递的参数,包括文件路径、写入内容、锁标志位和偏移位。
- 使用
-
线程安全写入:
- 在写入文件前,如果启用锁,则获取锁;写入完成后释放锁,确保线程安全。
- 通过修改共享内存中的偏移量,指定下次写入的位置,实现线程间的协作。
这个案例展示了如何在鸿蒙HarmonyOS NEXT开发中实现跨线程对象传递和共享内存,确保线程安全和数据一致性。通过使用 SharedArrayBuffer
和线程间参数传递,可以实现高效的并发编程。关注威哥爱编程,一起向鸿蒙出发。
本文来自博客园,作者:威哥爱编程,转载请注明原文链接:https://www.cnblogs.com/wgjava/p/18668050
合集:
威哥爱编程
标签:
harmonyos
, harmonyos next
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目