同步任務開發(fā)指導

2024-02-16 13:46 更新

同步任務是指在多個線程之間協(xié)調(diào)執(zhí)行的任務,其目的是確保多個任務按照一定的順序和規(guī)則執(zhí)行,例如使用鎖來防止數(shù)據(jù)競爭。

同步任務的實現(xiàn)需要考慮多個線程之間的協(xié)作和同步,以確保數(shù)據(jù)的正確性和程序的正確執(zhí)行。

由于TaskPool偏向于單個獨立的任務,因此當各個同步任務之間相對獨立時推薦使用TaskPool,例如一系列導入的靜態(tài)方法,或者單例實現(xiàn)的方法。如果同步任務之間有關(guān)聯(lián)性,則需要使用Worker,例如無法單例創(chuàng)建的類對象實現(xiàn)的方法。

使用TaskPool處理同步任務

當調(diào)度獨立的同步任務,或者一系列同步任務為靜態(tài)方法實現(xiàn),或者可以通過單例構(gòu)造唯一的句柄或類對象,可在不同任務池之間使用時,推薦使用TaskPool。

  1. 定義并發(fā)函數(shù),內(nèi)部調(diào)用同步方法。

  2. 創(chuàng)建任務,并通過TaskPool執(zhí)行,再對異步結(jié)果進行操作。創(chuàng)建Task,通過execute()執(zhí)行同步任務。

模擬一個包含同步調(diào)用的單實例類。

  1. // Handle.ts 代碼
  2. export default class Handle {
  3. static getInstance() {
  4. // 返回單例對象
  5. }
  6. static syncGet() {
  7. // 同步Get方法
  8. return;
  9. }
  10. static syncSet(num: number) {
  11. // 同步Set方法
  12. return;
  13. }
  14. }

業(yè)務使用TaskPool調(diào)用相關(guān)同步方法的代碼。

  1. // Index.ets代碼
  2. import taskpool from '@ohos.taskpool';
  3. import Handle from './Handle'; // 返回靜態(tài)句柄
  4. // 步驟1: 定義并發(fā)函數(shù),內(nèi)部調(diào)用同步方法
  5. @Concurrent
  6. function func(num: number) {
  7. // 調(diào)用靜態(tài)類對象中實現(xiàn)的同步等待調(diào)用
  8. Handle.syncSet(num);
  9. // 或者調(diào)用單例對象中實現(xiàn)的同步等待調(diào)用
  10. Handle.getInstance().syncGet();
  11. return true;
  12. }
  13. // 步驟2: 創(chuàng)建任務并執(zhí)行
  14. async function asyncGet() {
  15. // 創(chuàng)建task并傳入函數(shù)func
  16. let task = new taskpool.Task(func, 1);
  17. // 執(zhí)行task任務,獲取結(jié)果res
  18. let res = await taskpool.execute(task);
  19. // 對同步邏輯后的結(jié)果進行操作
  20. console.info(String(res));
  21. }
  22. @Entry
  23. @Component
  24. struct Index {
  25. @State message: string = 'Hello World';
  26. build() {
  27. Row() {
  28. Column() {
  29. Text(this.message)
  30. .fontSize(50)
  31. .fontWeight(FontWeight.Bold)
  32. .onClick(() => {
  33. // 步驟3: 執(zhí)行并發(fā)操作
  34. asyncGet();
  35. })
  36. }
  37. .width('100%')
  38. .height('100%')
  39. }
  40. }
  41. }

使用Worker處理關(guān)聯(lián)的同步任務

當一系列同步任務需要使用同一個句柄調(diào)度,或者需要依賴某個類對象調(diào)度,無法在不同任務池之間共享時,需要使用Worker。

  1. 在主線程中創(chuàng)建Worker對象,同時接收Worker線程發(fā)送回來的消息。

    1. import worker from '@ohos.worker';
    2. @Entry
    3. @Component
    4. struct Index {
    5. @State message: string = 'Hello World';
    6. build() {
    7. Row() {
    8. Column() {
    9. Text(this.message)
    10. .fontSize(50)
    11. .fontWeight(FontWeight.Bold)
    12. .onClick(() => {
    13. let w = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
    14. w.onmessage = function (d) {
    15. // 接收Worker子線程的結(jié)果
    16. }
    17. w.onerror = function (d) {
    18. // 接收Worker子線程的錯誤信息
    19. }
    20. // 向Worker子線程發(fā)送Set消息
    21. w.postMessage({'type': 0, 'data': 'data'})
    22. // 向Worker子線程發(fā)送Get消息
    23. w.postMessage({'type': 1})
    24. // ...
    25. // 根據(jù)實際業(yè)務,選擇時機以銷毀線程
    26. w.terminate()
    27. })
    28. }
    29. .width('100%')
    30. }
    31. .height('100%')
    32. }
    33. }
  2. 在Worker線程中綁定Worker對象,同時處理同步任務邏輯。

    1. // handle.ts代碼
    2. export default class Handle {
    3. syncGet() {
    4. return;
    5. }
    6. syncSet(num: number) {
    7. return;
    8. }
    9. }
    10. // MyWorker.ts代碼
    11. import worker, { ThreadWorkerGlobalScope, MessageEvents } from '@ohos.worker';
    12. import Handle from './handle.ts' // 返回句柄
    13. var workerPort : ThreadWorkerGlobalScope = worker.workerPort;
    14. // 無法傳輸?shù)木浔?,所有操作依賴此句?/span>
    15. var handler = new Handle()
    16. // Worker線程的onmessage邏輯
    17. workerPort.onmessage = function(e : MessageEvents) {
    18. switch (e.data.type) {
    19. case 0:
    20. handler.syncSet(e.data.data);
    21. workerPort.postMessage('success set');
    22. case 1:
    23. handler.syncGet();
    24. workerPort.postMessage('success get');
    25. }
    26. }
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號