1# Synchronous Task Development 2 3 4Synchronous tasks are executed in order among multiple threads. For example, as a synchronization primitive, locks prevent data contention. 5 6 7To implement synchronous tasks, you must consider the collaboration and synchronization between multiple threads and ensure the correctness of data and the correct execution of programs. 8 9If synchronous tasks are independent of each other, you are advised to use **TaskPool**, since it focuses on single independent tasks. For example, a series of imported static methods or methods implemented in singletons are independent. If synchronous tasks are associated with each other, use **Worker**, for example, methods implemented in class objects (not singleton class objects). 10 11 12## Using TaskPool to Process Independent Synchronous Tasks 13 14**TaskPool** is recommended for scheduling independent synchronous tasks. Typical synchronous tasks are those using static methods. If a unique handle or class object constructed using a singleton points to multiple tasks and these tasks can be used between different worker threads, you can also use **TaskPool**. 15 161. Define a concurrency function that internally calls the synchronous methods. 17 182. Create a task, execute the task through **TaskPool**, and perform operations on the asynchronous result. Create a [task](../reference/apis/js-apis-taskpool.md#task) and call [execute()](../reference/apis/js-apis-taskpool.md#taskpoolexecute-1) to execute the task synchronously. 19 203. Perform concurrent operations. 21 22Simulate a singleton class that contains synchronous calls. 23 24 25```ts 26// handle.ts code 27export default class Handle { 28 static getInstance() { 29 // Return a singleton object. 30 } 31 32 static syncGet() { 33 // Synchronous getter. 34 return; 35 } 36 37 static syncSet(num: number) { 38 // Synchronous setter. 39 return; 40 } 41} 42``` 43 44Use **TaskPool** to call the related synchronous methods. 45 46 47```ts 48// Index.ets code 49import taskpool from '@ohos.taskpool'; 50import Handle from './Handle'; // Return a static handle. 51 52// Step 1: Define a concurrency function that internally calls the synchronous methods. 53@Concurrent 54function func(num: number) { 55 // Call the synchronous wait implemented in a static class object. 56 Handle.syncSet(num); 57 // Alternatively, call the synchronous wait implemented in a singleton object. 58 Handle.getInstance().syncGet(); 59 return true; 60} 61 62// Step 2: Create and execute a task. 63async function asyncGet() { 64 // Create a task and pass in the function func. 65 let task = new taskpool.Task(func, 1); 66 // Execute the task and obtain the result res. 67 let res = await taskpool.execute(task); 68 // Perform operations on the synchronous result. 69 console.info(String(res)); 70} 71 72@Entry 73@Component 74struct Index { 75 @State message: string = 'Hello World'; 76 77 build() { 78 Row() { 79 Column() { 80 Text(this.message) 81 .fontSize(50) 82 .fontWeight(FontWeight.Bold) 83 .onClick(() => { 84 // Step 3: Perform concurrent operations. 85 asyncGet(); 86 }) 87 } 88 .width('100%') 89 .height('100%') 90 } 91 } 92} 93``` 94 95 96## Using Worker to Process Associated Synchronous Tasks 97 98Use **Worker** when you want to schedule a series of synchronous tasks using the same handle or depending on the same class object. 99 1001. Create a **Worker** object in the main thread and receive messages from the worker thread. 101 102 ```js 103 import worker from '@ohos.worker'; 104 105 @Entry 106 @Component 107 struct Index { 108 @State message: string = 'Hello World'; 109 110 build() { 111 Row() { 112 Column() { 113 Text(this.message) 114 .fontSize(50) 115 .fontWeight(FontWeight.Bold) 116 .onClick(() => { 117 let w = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts'); 118 w.onmessage = function (d) { 119 // Receive the result of the worker thread. 120 } 121 w.onerror = function (d) { 122 // Receive error information of the worker thread. 123 } 124 // Send a Set message to the worker thread. 125 w.postMessage({'type': 0, 'data': 'data'}) 126 // Send a Get message to the worker thread. 127 w.postMessage({'type': 1}) 128 // Destroy the worker thread. 129 w.terminate() 130 }) 131 } 132 .width('100%') 133 } 134 .height('100%') 135 } 136 } 137 ``` 138 1392. Bind the **Worker** object in the worker thread and process the synchronous task logic. 140 141 ```js 142 // handle.ts code 143 export default class Handle { 144 syncGet() { 145 return; 146 } 147 148 syncSet(num: number) { 149 return; 150 } 151 } 152 153 // Worker.ts code 154 import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker'; 155 import Handle from './handle.ts' // Return a handle. 156 157 var workerPort : ThreadWorkerGlobalScope = worker.workerPort; 158 159 // Handle that cannot be transferred. All operations depend on this handle. 160 var handler = new Handle() 161 162 // onmessage() logic of the worker thread. 163 workerPort.onmessage = function(e : MessageEvents) { 164 switch (e.data.type) { 165 case 0: 166 handler.syncSet(e.data.data); 167 workerPort.postMessage('success set'); 168 case 1: 169 handler.syncGet(); 170 workerPort.postMessage('success get'); 171 } 172 } 173 ``` 174