• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 同步任务开发指导
2
3
4同步任务是指在多个线程之间协调执行的任务,其目的是确保多个任务按照一定的顺序和规则执行,例如使用锁来防止数据竞争。
5
6
7同步任务的实现需要考虑多个线程之间的协作和同步,以确保数据的正确性和程序的正确执行。
8
9由于TaskPool偏向于单个独立的任务,因此当各个同步任务之间相对独立时推荐使用TaskPool,例如一系列导入的静态方法,或者单例实现的方法。如果同步任务之间有关联性,则需要使用Worker,例如无法单例创建的类对象实现的方法。
10
11
12## 使用TaskPool处理同步任务
13
14当调度独立的同步任务,或者一系列同步任务为静态方法实现,或者可以通过单例构造唯一的句柄或类对象,可在不同任务池之间使用时,推荐使用TaskPool。
15
161. 定义并发函数,内部调用同步方法。
17
182. 创建任务,并通过TaskPool执行,再对异步结果进行操作。创建[Task](../reference/apis/js-apis-taskpool.md#task),并通过[execute()](../reference/apis/js-apis-taskpool.md#taskpoolexecute-1)接口执行同步任务。
19
203. 执行并发操作。
21
22模拟一个包含同步调用的单实例类。
23
24
25```ts
26// Handle.ts 代码
27export default class Handle {
28  static getInstance() {
29    // 返回单例对象
30  }
31
32  static syncGet() {
33    // 同步Get方法
34    return;
35  }
36
37  static syncSet(num: number) {
38    // 同步Set方法
39    return;
40  }
41}
42```
43
44业务使用TaskPool调用相关同步方法的代码。
45
46
47```ts
48// Index.ets代码
49import taskpool from '@ohos.taskpool';
50import Handle from './Handle'; // 返回静态句柄
51
52// 步骤1: 定义并发函数,内部调用同步方法
53@Concurrent
54function func(num: number) {
55  // 调用静态类对象中实现的同步等待调用
56  Handle.syncSet(num);
57  // 或者调用单例对象中实现的同步等待调用
58  Handle.getInstance().syncGet();
59  return true;
60}
61
62// 步骤2: 创建任务并执行
63async function asyncGet() {
64  // 创建task并传入函数func
65  let task = new taskpool.Task(func, 1);
66  // 执行task任务,获取结果res
67  let res = await taskpool.execute(task);
68  // 对同步逻辑后的结果进行操作
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            // 步骤3: 执行并发操作
85            asyncGet();
86          })
87      }
88      .width('100%')
89      .height('100%')
90    }
91  }
92}
93```
94
95
96## 使用Worker处理关联的同步任务
97
98当一系列同步任务需要使用同一个句柄调度,或者需要依赖某个类对象调度,无法在不同任务池之间共享时,需要使用Worker。
99
1001. 在主线程中创建Worker对象,同时接收Worker线程发送回来的消息。
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                 // 接收Worker子线程的结果
120               }
121               w.onerror = function (d) {
122                 // 接收Worker子线程的错误信息
123               }
124               // 向Worker子线程发送Set消息
125               w.postMessage({'type': 0, 'data': 'data'})
126               // 向Worker子线程发送Get消息
127               w.postMessage({'type': 1})
128               // 销毁线程
129               w.terminate()
130             })
131         }
132         .width('100%')
133       }
134       .height('100%')
135     }
136   }
137   ```
138
1392. 在Worker线程中绑定Worker对象,同时处理同步任务逻辑。
140
141   ```js
142   // handle.ts代码
143   export default class Handle {
144     syncGet() {
145       return;
146     }
147
148     syncSet(num: number) {
149       return;
150     }
151   }
152
153   // Worker.ts代码
154   import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker';
155   import Handle from './handle.ts'  // 返回句柄
156
157   var workerPort : ThreadWorkerGlobalScope = worker.workerPort;
158
159   // 无法传输的句柄,所有操作依赖此句柄
160   var handler = new Handle()
161
162   // Worker线程的onmessage逻辑
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