1# 同步任务开发指导 (TaskPool和Worker) 2<!--Kit: ArkTS--> 3<!--Subsystem: CommonLibrary--> 4<!--Owner: @lijiamin2025--> 5<!--Designer: @weng-changcheng--> 6<!--Tester: @kirl75; @zsw_zhushiwei--> 7<!--Adviser: @ge-yafang--> 8 9 10同步任务用于在多个线程间协调执行,确保任务按特定顺序和规则进行(如使用锁防止数据竞争)。 11 12 13同步任务的实现需要考虑多个线程之间的协作和同步,以确保数据的正确性和程序的正确执行。 14 15当同步任务之间相对独立时,推荐使用TaskPool,例如一系列导入的静态方法或单例实现的方法。如果同步任务之间有关联性,则需要使用Worker。 16 17 18## 使用TaskPool处理同步任务 19 20以下场景推荐使用TaskPool。 21 22- 调度相互独立的任务。 23 24- 静态方法实现的任务。 25 26- 单例构造的句柄或者类对象跨线程使用。 27 28> **说明:** 29> 30> 由于[Actor模型](multi-thread-concurrency-overview.md#actor模型)不同线程间内存隔离的特性,普通单例无法在不同线程间使用。可通过共享模块导出单例解决此问题。 31 321. 定义并发函数,实现业务逻辑。 33 342. 创建任务[Task](../reference/apis-arkts/js-apis-taskpool.md#task),通过[execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute-1)接口执行该任务。 35 363. 对任务返回的结果进行操作。 37 38如下示例中业务使用TaskPool调用相关同步方法的代码,首先定义并发函数taskpoolFunc,需要注意必须使用[@Concurrent装饰器](taskpool-introduction.md#concurrent装饰器)装饰该函数;其次定义函数mainFunc,该函数功能为创建任务,执行任务并处理任务返回的结果。 39 40 41```ts 42// Index.ets 43import { taskpool} from '@kit.ArkTS'; 44 45// 步骤1: 定义并发函数,实现业务逻辑 46@Concurrent 47async function taskpoolFunc(num: number): Promise<number> { 48 // 根据业务逻辑实现相应的功能 49 let tmpNum: number = num + 100; 50 return tmpNum; 51} 52 53async function mainFunc(): Promise<void> { 54 // 步骤2: 创建任务并执行 55 let task1: taskpool.Task = new taskpool.Task(taskpoolFunc, 1); 56 let res1: number = await taskpool.execute(task1) as number; 57 let task2: taskpool.Task = new taskpool.Task(taskpoolFunc, res1); 58 let res2: number = await taskpool.execute(task2) as number; 59 // 步骤3: 对任务返回的结果进行操作 60 console.info("taskpool: task res1 is: " + res1); 61 console.info("taskpool: task res2 is: " + res2); 62} 63 64@Entry 65@Component 66struct Index { 67 @State message: string = 'Hello World'; 68 69 build() { 70 Row() { 71 Column() { 72 Text(this.message) 73 .fontSize(50) 74 .fontWeight(FontWeight.Bold) 75 .onClick(async () => { 76 mainFunc(); 77 }) 78 } 79 .width('100%') 80 .height('100%') 81 } 82 } 83} 84``` 85<!-- @[taskpool_handle_sync_task](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/ApplicationMultithreading/entry/src/main/ets/managers/SyncTaskDevelopment.ets) --> 86 87 88## 使用Worker处理关联的同步任务 89 90当一系列同步任务需要使用同一个句柄调度,或者需要依赖某个类对象调度,且无法在不同任务池之间共享时,需要使用Worker。 91 921. 在UI主线程中创建Worker对象并接收Worker线程发送的消息。DevEco Studio支持一键生成Worker。在{moduleName}目录下任意位置,点击鼠标右键 > New > Worker,即可生成Worker的模板文件及配置信息。 93 94 ```ts 95 // Index.ets 96 import { MessageEvents, worker } from '@kit.ArkTS'; 97 98 @Entry 99 @Component 100 struct Index { 101 @State message: string = 'Hello World'; 102 103 build() { 104 Row() { 105 Column() { 106 Text(this.message) 107 .fontSize(50) 108 .fontWeight(FontWeight.Bold) 109 .onClick(() => { 110 let w: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/Worker.ets'); 111 // 向Worker子线程发送Set消息 112 w.postMessage({'type': 0, 'data': 10}); 113 // 向Worker子线程发送Get消息 114 w.postMessage({'type': 1}); 115 // 接收Worker子线程的结果 116 w.onmessage = (e: MessageEvents): void => { 117 // 接收Worker子线程的结果 118 console.info('main thread onmessage, ' + e.data); 119 // 销毁Worker 120 w.terminate(); 121 } 122 }) 123 } 124 .width('100%') 125 } 126 .height('100%') 127 } 128 } 129 ``` 130 <!-- @[worker_handle_associated_sync_task](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/ApplicationMultithreading/entry/src/main/ets/managers/SyncTaskDevelopment.ets) --> 131 132 1332. 在Worker线程中绑定Worker对象,同时处理同步任务逻辑。 134 135 ```ts 136 // handle.ts代码,与Worker.ets在同级目录下 137 export default class Handle { 138 id: number = 0; 139 140 syncGet(): number { 141 return this.id; 142 } 143 144 syncSet(num: number): boolean { 145 this.id = num; 146 return true; 147 } 148 } 149 ``` 150 <!-- @[worker_handle_associated_sync_task](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/ApplicationMultithreading/entry/src/main/ets/workers/handle.ts) --> 151 152 ```ts 153 // Worker.ets 154 import { worker, ThreadWorkerGlobalScope, MessageEvents } from '@kit.ArkTS'; 155 // 返回句柄 156 import Handle from './handle'; 157 158 let workerPort : ThreadWorkerGlobalScope = worker.workerPort; 159 160 // 无法传输的句柄,所有操作依赖此句柄 161 let handler: Handle = new Handle(); 162 163 // Worker线程的onmessage逻辑 164 workerPort.onmessage = (e : MessageEvents): void => { 165 switch (e.data.type as number) { 166 case 0: 167 let result: boolean = false; 168 result = handler.syncSet(e.data.data); 169 console.info("worker: result is " + result); 170 workerPort.postMessage('the result of syncSet() is ' + result); 171 break; 172 case 1: 173 let num: number = 0; 174 num = handler.syncGet(); 175 console.info("worker: num is " + num); 176 workerPort.postMessage('the result of syncGet() is ' + num); 177 break; 178 } 179 } 180 ``` 181 <!-- @[worker_handle_associated_sync_task](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ApplicationMultithreadingDevelopment/ApplicationMultithreading/entry/src/main/ets/workers/MyWorker2.ts) --> 182