一、前置思考HarmonyOS的ArkUI是单线程渲染模型UI更新只能在主线程执行任何阻塞主线程超过16.67ms的操作都会导致丢帧。这时候多线程就成了标配——把计算密集型任务扔到后台线程主线程专注UI。但HarmonyOS的多线程方案和Android/iOS不一样没有Java的Thread类没有iOS的GCDGrand Central Dispatch有的是TaskPool和Worker两套并发方案本文将深入对比这两套方案给出工业级的调度策略。二、核心原理2.1 TaskPool vs Worker对比维度TaskPoolWorker定位短任务并发池长生命周期后台线程线程模型线程池复用独立线程创建开销低复用池中线程高独立创建生命周期任务结束即释放长期存活需手动销毁通信方式Concurrent函数调用postMessage/onMessage数量限制无自动调度最多8个适用场景图片解码、排序、加密持续监听、大文件传输2.3 TaskPool使用模式import{taskpool}fromkit.ArkTS;ConcurrentfunctiondecodeImage(data:ArrayBuffer):ImageBitmap{// 在TaskPool线程执行constdecoderimage.createImageSource(data);// ...returnbitmap;}// 主线程调用consttask:taskpool.Tasknewtaskpool.Task(decodeImage,rawData);taskpool.execute(task).then((result:Object){constbitmap:ImageBitmapresultasImageBitmap;// 更新UI});2.4 Worker使用模式import{worker}fromkit.ArkTS;// 创建WorkerconstworkerInstance:worker.ThreadWorkernewworker.ThreadWorker(entry/ets/workers/MyWorker.ets);// 发送消息workerInstance.postMessage({cmd:start,data:largeData});// 接收结果workerInstance.onmessage(e:MessageEvents):void{constresult:Objecte.data;// 更新UI};// 销毁workerInstance.terminate();2.5 Concurrent装饰器约束只能装饰全局函数不能装饰类方法参数和返回值必须是可序列化类型函数内不能访问闭包变量不能调用UI相关API三、企业级实战落地本Demo演示场景方案演示内容图片处理TaskPool模拟图片解码/压缩数据排序TaskPool10000条数据排序文件监听Worker模拟大文件传输进度Worker通信postMessage双向消息线程数对比多任务并发3个Task vs 3个Worker四、调度策略任务类型推荐方案理由耗时100ms主线程线程切换开销可能更大100ms~1sTaskPool低开销自动调度1s的持续任务Worker独立线程避免阻塞池需要持续通信WorkerpostMessage双向通道大量并发短任务TaskPool线程池复用效率高五、避坑速查坑现象解决Concurrent函数访问this编译报错用全局函数数据通过参数传递Worker文件路径错误Worker创建失败路径格式entry/ets/workers/...Worker未terminate内存泄漏aboutToDisappear中terminateTaskPool中抛异常不捕获主线程无响应.catch()处理Worker数量超8创建失败复用已有Worker或改用TaskPool六、总结**口诀短任务用TaskPool长任务用Worker。**不要在一个应用中创建超过4个Worker大多数场景TaskPool已经足够。对应Demo文件entry/src/main/ets/pages/ThreadSchedulingDemo.ets
鸿蒙线程调度:TaskPool并发框架对比剖析/Worker线程隔离/Callable分时复用工业级实战
一、前置思考HarmonyOS的ArkUI是单线程渲染模型UI更新只能在主线程执行任何阻塞主线程超过16.67ms的操作都会导致丢帧。这时候多线程就成了标配——把计算密集型任务扔到后台线程主线程专注UI。但HarmonyOS的多线程方案和Android/iOS不一样没有Java的Thread类没有iOS的GCDGrand Central Dispatch有的是TaskPool和Worker两套并发方案本文将深入对比这两套方案给出工业级的调度策略。二、核心原理2.1 TaskPool vs Worker对比维度TaskPoolWorker定位短任务并发池长生命周期后台线程线程模型线程池复用独立线程创建开销低复用池中线程高独立创建生命周期任务结束即释放长期存活需手动销毁通信方式Concurrent函数调用postMessage/onMessage数量限制无自动调度最多8个适用场景图片解码、排序、加密持续监听、大文件传输2.3 TaskPool使用模式import{taskpool}fromkit.ArkTS;ConcurrentfunctiondecodeImage(data:ArrayBuffer):ImageBitmap{// 在TaskPool线程执行constdecoderimage.createImageSource(data);// ...returnbitmap;}// 主线程调用consttask:taskpool.Tasknewtaskpool.Task(decodeImage,rawData);taskpool.execute(task).then((result:Object){constbitmap:ImageBitmapresultasImageBitmap;// 更新UI});2.4 Worker使用模式import{worker}fromkit.ArkTS;// 创建WorkerconstworkerInstance:worker.ThreadWorkernewworker.ThreadWorker(entry/ets/workers/MyWorker.ets);// 发送消息workerInstance.postMessage({cmd:start,data:largeData});// 接收结果workerInstance.onmessage(e:MessageEvents):void{constresult:Objecte.data;// 更新UI};// 销毁workerInstance.terminate();2.5 Concurrent装饰器约束只能装饰全局函数不能装饰类方法参数和返回值必须是可序列化类型函数内不能访问闭包变量不能调用UI相关API三、企业级实战落地本Demo演示场景方案演示内容图片处理TaskPool模拟图片解码/压缩数据排序TaskPool10000条数据排序文件监听Worker模拟大文件传输进度Worker通信postMessage双向消息线程数对比多任务并发3个Task vs 3个Worker四、调度策略任务类型推荐方案理由耗时100ms主线程线程切换开销可能更大100ms~1sTaskPool低开销自动调度1s的持续任务Worker独立线程避免阻塞池需要持续通信WorkerpostMessage双向通道大量并发短任务TaskPool线程池复用效率高五、避坑速查坑现象解决Concurrent函数访问this编译报错用全局函数数据通过参数传递Worker文件路径错误Worker创建失败路径格式entry/ets/workers/...Worker未terminate内存泄漏aboutToDisappear中terminateTaskPool中抛异常不捕获主线程无响应.catch()处理Worker数量超8创建失败复用已有Worker或改用TaskPool六、总结**口诀短任务用TaskPool长任务用Worker。**不要在一个应用中创建超过4个Worker大多数场景TaskPool已经足够。对应Demo文件entry/src/main/ets/pages/ThreadSchedulingDemo.ets