日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HarmonyOS之深入解析线程管理

發布時間:2024/5/21 编程问答 86 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HarmonyOS之深入解析线程管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、簡介

  • 不同應用在各自獨立的進程中運行。當應用以任何形式啟動時,系統為其創建進程,該進程將持續運行。當進程完成當前任務處于等待狀態,且系統資源不足時,系統自動回收。
  • 在啟動應用時,系統會為該應用創建一個稱為“主線程”的執行線程。該線程隨著應用創建或消失,是應用的核心線程。
  • UI 界面的顯示和更新等操作,都是在主線程上進行。主線程又稱 UI 線程,默認情況下,所有的操作都是在主線程上執行。如果需要執行比較耗時的任務(如下載文件、查詢數據庫),可創建其他線程來處理。
  • 如果應用的業務邏輯比較復雜,可能需要創建多個線程來執行多個任務,這種情況下,代碼復雜難以維護,任務與線程的交互也會更加繁雜。要解決此問題,可以使用“TaskDispatcher”來分發不同的任務。

二、API 說明

  • TaskDispatcher 是一個任務分發器,它是 Ability 分發任務的基本接口,隱藏任務所在線程的實現細節。
  • 為保證應用有更好的響應性,需要設計任務的優先級。在 UI 線程上運行的任務默認以高優先級運行,如果某個任務無需等待結果,則可以用低優先級。
  • 線程優先級說明:
優先級詳細描述
HIGH最高任務優先級,比默認優先級、低優先級的任務有更高的幾率得到執行
DEFAULT默認任務優先級, 比低優先級的任務有更高的幾率得到執行
LOW低任務優先級,比高優先級、默認優先級的任務有更低的幾率得到執行
  • TaskDispatcher 具有多種實現,每種實現對應不同的任務分發器。在分發任務時可以指定任務的優先級,由同一個任務分發器分發出的任務具有相同的優先級。
  • 系統提供的任務分發器有 GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。
  • GlobalTaskDispatcher:全局并發任務分發器,由 Ability 執行 getGlobalTaskDispatcher() 獲取,適用于任務之間沒有聯系的情況。一個應用只有一個 GlobalTaskDispatcher,它在程序結束時才被銷毀。
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
  • ParallelTaskDispatcher:并發任務分發器,由 Ability 執行 createParallelTaskDispatcher() 創建并返回。與 GlobalTaskDispatcher 不同的是,ParallelTaskDispatcher 不具有全局唯一性,可以創建多個,在創建或銷毀 dispatcher 時,需要持有對應的對象引用。
String dispatcherName = "parallelTaskDispatcher";TaskDispatcher parallelTaskDispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
  • SerialTaskDispatcher:串行任務分發器,由 Ability 執行 createSerialTaskDispatcher() 創建并返回。由該分發器分發的所有的任務都是按順序執行,但是執行這些任務的線程并不是固定的。
    • 如果要執行并行任務,應使用 ParallelTaskDispatcher 或者 GlobalTaskDispatcher,而不是創建多個 SerialTaskDispatcher。
    • 如果任務之間沒有依賴,應使用 GlobalTaskDispatcher 來實現。它的創建和銷毀由開發者自己管理,在使用期間需要持有該對象引用。
String dispatcherName = "serialTaskDispatcher";TaskDispatcher serialTaskDispatcher = createSerialTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
  • SpecTaskDispatcher:專有任務分發器,綁定到專有線程上的任務分發器。目前已有的專有線程為UI線程,通過 UITaskDispatcher 進行任務分發。
  • UITaskDispatcher:綁定到應用主線程的專有任務分發器, 由 Ability 執行 getUITaskDispatcher() 創建并返回。 由該分發器分發的所有的任務都是在主線程上按順序執行,它在應用程序結束時被銷毀。
TaskDispatcher uiTaskDispatcher = getUITaskDispatcher();

三、線程開發流程

① syncDispatch
  • 同步派發任務:派發任務并在當前線程等待任務執行完成。在返回前,當前線程會被阻塞。
  • 如下代碼示例,展示了如何使用 GlobalTaskDispatcher 派發同步任務:
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);globalTaskDispatcher.syncDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "sync task1 run");}});HiLog.info(LABEL_LOG, "after sync task1");globalTaskDispatcher.syncDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "sync task2 run");}});HiLog.info(LABEL_LOG, "after sync task2");globalTaskDispatcher.syncDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "sync task3 run");}});HiLog.info(LABEL_LOG, "after sync task3");// 執行結果如下:// sync task1 run// after sync task1// sync task2 run// after sync task2// sync task3 run// after sync task3
  • 如果對 syncDispatch 使用不當,將會導致死鎖。如下情形可能導致死鎖發生:
    • 在專有線程上,利用該專有任務分發器進行 syncDispatch。
    • 在被某個串行任務分發器(dispatcher_a)派發的任務中,再次利用同一個串行任務分發器(dispatcher_a)對象派發任務。
    • 在被某個串行任務分發器(dispatcher_a)派發的任務中,經過數次派發任務,最終又利用該(dispatcher_a)串行任務分發器派發任務。例如:dispatcher_a 派發的任務使用 dispatcher_b 進行任務的派發,在 dispatcher_b 派發的任務中又利用 dispatcher_a 進行派發任務。
    • 串行任務分發器(dispatcher_a)派發的任務中利用串行任務分發器(dispatcher_b)進行同步派發任務,同時 dispatcher_b 派發的任務中利用串行任務分發器(dispatcher_a)進行同步派發任務。在特定的線程執行順序下將導致死鎖。
② asyncDispatch
  • 異步派發任務:派發任務,并立即返回,返回值是一個可用于取消任務的接口。
  • 如下代碼示例,展示了如何使用 GlobalTaskDispatcher 派發異步任務:
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);Revocable revocable = globalTaskDispatcher.asyncDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "async task1 run");}});HiLog.info(LABEL_LOG, "after async task1");// 執行結果可能如下:// after async task1// async task1 run
③ delayDispatch
  • 異步延遲派發任務:異步執行,函數立即返回,內部會在延時指定時間后將任務派發到相應隊列中。延時時間參數僅代表在這段時間以后任務分發器會將任務加入到隊列中,任務的實際執行時間可能晚于這個時間。具體比這個數值晚多久,取決于隊列及內部線程池的繁忙情況。
  • 如下代碼示例,展示了如何使用 GlobalTaskDispatcher 延遲派發任務:
final long callTime = System.currentTimeMillis();final long delayTime = 50L;TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); Revocable revocable = globalTaskDispatcher.delayDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "delayDispatch task1 run");final long actualDelay = System.currentTimeMillis() - callTime;HiLog.info(LABEL_LOG, "actualDelayTime >= delayTime: %{public}b", (actualDelay >= delayTime));}}, delayTime);HiLog.info(LABEL_LOG, "after delayDispatch task1");// 執行結果可能如下:// after delayDispatch task1// delayDispatch task1 run// actualDelayTime >= delayTime : true
④ Group
  • 任務組:表示一組任務,且該組任務之間有一定的聯系,由 TaskDispatcher 執行 createDispatchGroup 創建并返回。將任務加入任務組,返回一個用于取消任務的接口。
  • 如下代碼示例展示了任務組的使用方式:將一系列相關聯的下載任務放入一個任務組,執行完下載任務后關閉應用。
String dispatcherName = "parallelTaskDispatcher";TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);// 創建任務組。Group group = dispatcher.createDispatchGroup();// 將任務1加入任務組,返回一個用于取消任務的接口。dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "download task1 is running");}});// 將與任務1相關聯的任務2加入任務組。dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "download task2 is running");}});// 在任務組中的所有任務執行完成后執行指定任務。dispatcher.groupDispatchNotify(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "the close task is running after all tasks in the group are completed");}});?// 可能的執行結果:// download task1 is running// download task2 is running// the close task is running after all tasks in the group are completed// 另外一種可能的執行結果:// download task2 is running// download task1 is running// the close task is running after all tasks in the group are completed
⑤ Revocable
  • 取消任務:Revocable 是取消一個異步任務的接口。異步任務包括通過 asyncDispatch、delayDispatch、asyncGroupDispatch 派發的任務。如果任務已經在執行中或執行完成,則會返回取消失敗。
  • 如下代碼示例展示了如何取消一個異步延時任務:
TaskDispatcher dispatcher = getUITaskDispatcher();Revocable revocable = dispatcher.delayDispatch(new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "delay dispatch");}}, 10);boolean revoked = revocable.revoke();HiLog.info(LABEL_LOG, "%{public}b", revoked);?// 一種可能的結果如下 :// true
⑥ syncDispatchBarrier
  • 同步設置屏障任務:在任務組上設立任務執行屏障,同步等待任務組中的所有任務執行完成,再執行指定任務。
  • 在全局并發任務分發器(GlobalTaskDispatcher)上同步設置任務屏障,將不會起到屏障作用。
  • 如下代碼示例展示了如何同步設置屏障:
String dispatcherName = "parallelTaskDispatcher";TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);// 創建任務組。Group group = dispatcher.createDispatchGroup();// 將任務加入任務組,返回一個用于取消任務的接口。dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "task1 is running"); // 1}});dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "task2 is running"); // 2}});dispatcher.syncDispatchBarrier(new Runnable() {@Overridepublic void run() { HiLog.info(LABEL_LOG, "barrier"); // 3}}); HiLog.info(LABEL_LOG, "after syncDispatchBarrier"); // 4?// 1和2的執行順序不定;3和4總是在1和2之后按順序執行。// 可能的執行結果:// task1 is running// task2 is running// barrier// after syncDispatchBarrier// 另外一種執行結果:// task2 is running// task1 is running// barrier// after syncDispatchBarrier
⑦ asyncDispatchBarrier
  • 異步設置屏障任務:在任務組上設立任務執行屏障后直接返回,指定任務將在任務組中的所有任務執行完成后再執行。
  • 在全局并發任務分發器(GlobalTaskDispatcher)上異步設置任務屏障,將不會起到屏障作用。可以使用并發任務分發器(ParallelTaskDispatcher)分離不同的任務組,達到微觀并行、宏觀串行的行為。
  • 如下代碼示例展示了如何異步設置屏障:
TaskDispatcher dispatcher = createParallelTaskDispatcher("dispatcherName", TaskPriority.DEFAULT);// 創建任務組Group group = dispatcher.createDispatchGroup();// 將任務加入任務組,返回一個用于取消任務的接口dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "task1 is running"); // 1}});dispatcher.asyncGroupDispatch(group, new Runnable() {@Overridepublic void run() {HiLog.info(LABEL_LOG, "task2 is running"); // 2}});dispatcher.asyncDispatchBarrier(new Runnable() {@Overridepublic void run() { HiLog.info(LABEL_LOG, "barrier"); // 3}}); HiLog.info(LABEL_LOG, "after asyncDispatchBarrier"); // 4?// 1和2的執行順序不定,但總在3之前執行;4不需要等待1、2、3執行完成// 可能的執行結果:// task1 is running// task2 is running// after asyncDispatchBarrier// barrier
⑧ applyDispatch
  • 執行多次任務:對指定任務執行多次。
  • 如下代碼示例展示了如何執行多次任務:
final int total = 10;final CountDownLatch latch = new CountDownLatch(total);final List<Long> indexList = new ArrayList<>(total);TaskDispatcher dispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); // 執行任務 total 次。dispatcher.applyDispatch((index) -> {indexList.add(index);latch.countDown();}, total);// 設置任務超時。try { latch.await();} catch (InterruptedException exception) {HiLog.error(LABEL_LOG, "latch exception");}HiLog.info(LABEL_LOG, "list size matches, %{public}b", (total == indexList.size()));// 執行結果:// list size matches, true

總結

以上是生活随笔為你收集整理的HarmonyOS之深入解析线程管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。