1# 同步任务开发指导 (TaskPool和Worker) 2 3 4同步任务是指在多个线程之间协调执行的任务,其目的是确保多个任务按照一定的顺序和规则执行,例如使用锁来防止数据竞争。 5 6 7同步任务的实现需要考虑多个线程之间的协作和同步,以确保数据的正确性和程序的正确执行。 8 9由于TaskPool偏向于单个独立的任务,因此当各个同步任务之间相对独立时推荐使用TaskPool,例如一系列导入的静态方法,或者单例实现的方法。如果同步任务之间有关联性,则需要使用Worker,例如无法单例创建的类对象实现的方法。 10 11 12## 使用TaskPool处理同步任务 13 14当调度独立的任务,或者一系列任务为静态方法实现,或者可以通过单例构造唯一的句柄或类对象,可在不同任务线程之间使用时,推荐使用TaskPool。 15 161. 定义并发函数,内部调用同步方法。 17 182. 创建任务[Task](../reference/apis-arkts/js-apis-taskpool.md#task),通过[execute()](../reference/apis-arkts/js-apis-taskpool.md#taskpoolexecute-1)接口执行该任务,并对任务返回的结果进行操作。 19 203. 执行并发操作。 21 22模拟一个包含同步调用的单实例类。 23 24 25```ts 26// Handle.ts 代码 27export default class Handle { 28 static getInstance(): void { 29 // 返回单例对象 30 } 31 32 static syncGet(): void { 33 // 同步Get方法 34 } 35 36 static syncSet(num: number): number { 37 // 模拟同步步骤1 38 console.info("taskpool: this is 1st print!"); 39 // 模拟同步步骤2 40 console.info("taskpool: this is 2nd print!"); 41 return num++; 42 } 43} 44``` 45 46 47业务使用TaskPool调用相关同步方法的代码。 48 49 50```ts 51// Index.ets代码 52import taskpool from '@ohos.taskpool'; 53import Handle from './Handle'; // 返回静态句柄 54 55// 步骤1: 定义并发函数,内部调用同步方法 56@Concurrent 57function func(num: number): boolean { 58 // 调用静态类对象中实现的同步等待调用 59 Handle.syncSet(num); 60 return true; 61} 62 63// 步骤2: 创建任务并执行 64async function asyncGet(): Promise<void> { 65 // 创建task并传入函数func 66 let task: taskpool.Task = new taskpool.Task(func, 1); 67 // 执行task任务 68 let res: boolean = await taskpool.execute(task) as boolean; 69 // 打印任务结果 70 console.info("taskpool: task res is: " + res); 71} 72 73@Entry 74@Component 75struct Index { 76 @State message: string = 'Hello World'; 77 78 build() { 79 Row() { 80 Column() { 81 Text(this.message) 82 .fontSize(50) 83 .fontWeight(FontWeight.Bold) 84 .onClick(() => { 85 // 步骤3: 执行并发操作 86 asyncGet(); 87 }) 88 } 89 .width('100%') 90 .height('100%') 91 } 92 } 93} 94``` 95 96 97## 使用Worker处理关联的同步任务 98 99当一系列同步任务需要使用同一个句柄调度,或者需要依赖某个类对象调度,无法在不同任务池之间共享时,需要使用Worker。 100 1011. 在主线程中创建Worker对象,同时接收Worker线程发送回来的消息。 102 103 ```ts 104 import worker from '@ohos.worker'; 105 106 @Entry 107 @Component 108 struct Index { 109 @State message: string = 'Hello World'; 110 111 build() { 112 Row() { 113 Column() { 114 Text(this.message) 115 .fontSize(50) 116 .fontWeight(FontWeight.Bold) 117 .onClick(() => { 118 let w: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts'); 119 w.onmessage = (): void => { 120 // 接收Worker子线程的结果 121 } 122 w.onerror = (): void => { 123 // 接收Worker子线程的错误信息 124 } 125 // 向Worker子线程发送Set消息 126 w.postMessage({'type': 0, 'data': 'data'}) 127 // 向Worker子线程发送Get消息 128 w.postMessage({'type': 1}) 129 // ... 130 // 根据实际业务,选择时机以销毁线程 131 w.terminate() 132 }) 133 } 134 .width('100%') 135 } 136 .height('100%') 137 } 138 } 139 ``` 140 141 1422. 在Worker线程中绑定Worker对象,同时处理同步任务逻辑。 143 144 ```ts 145 // handle.ts代码 146 export default class Handle { 147 syncGet() { 148 return; 149 } 150 151 syncSet(num: number) { 152 return; 153 } 154 } 155 ``` 156 157 ```ts 158 // MyWorker.ts代码 159 import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker'; 160 import Handle from './handle' // 返回句柄 161 162 let workerPort : ThreadWorkerGlobalScope = worker.workerPort; 163 164 // 无法传输的句柄,所有操作依赖此句柄 165 let handler: Handle = new Handle() 166 167 // Worker线程的onmessage逻辑 168 workerPort.onmessage = (e : MessageEvents): void => { 169 switch (e.data.type as number) { 170 case 0: 171 handler.syncSet(e.data.data); 172 workerPort.postMessage('success set'); 173 case 1: 174 handler.syncGet(); 175 workerPort.postMessage('success get'); 176 } 177 } 178 ``` 179