• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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