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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HarmonyOS之深入解析线程间的通信

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

一、概述

① 基本概念
  • 在開發過程中,開經常需要在當前線程中處理下載任務等較為耗時的操作,但是又不希望當前的線程受到阻塞。此時,就可以使用 EventHandler 機制。
  • EventHandler 是 HarmonyOS 用于處理線程間通信的一種機制,可以通過 EventRunner 創建新線程,將耗時的操作放到新線程上執行。這樣既不阻塞原來的線程,任務又可以得到合理的處理。比如:主線程使用 EventHandler 創建子線程,子線程做耗時的下載圖片操作,下載完成后,子線程通過 EventHandler 通知主線程,主線程再更新 UI。
  • EventRunner 是一種事件循環器,循環處理從該 EventRunner 創建的新線程的事件隊列中獲取 InnerEvent 事件或者 Runnable 任務。InnerEvent 是 EventHandler 投遞的事件。
  • EventHandler 是一種用戶在當前線程上投遞 InnerEvent 事件或者 Runnable 任務到異步線程上處理的機制。每一個 EventHandler 和指定的 EventRunner 所創建的新線程綁定,并且該新線程內部有一個事件隊列。EventHandler 可以投遞指定的 InnerEvent 事件或 Runnable 任務到這個事件隊列。EventRunner 從事件隊列里循環地取出事件,如果取出的事件是 InnerEvent 事件,將在 EventRunner 所在線程執行 processEvent 回調;如果取出的事件是 Runnable 任務,將在 EventRunner 所在線程執行 Runnable 的 run 回調。
  • 一般,EventHandler 有兩個主要作用:
    • 在不同線程間分發和處理 InnerEvent 事件或 Runnable 任務。
    • 延遲處理 InnerEvent 事件或 Runnable 任務。
② 運作機制
  • EventHandler 的運作機制如下圖所示:

  • 使用 EventHandler 實現線程間通信的主要流程:
    • EventHandler 投遞具體的 InnerEvent 事件或者 Runnable 任務到 EventRunner 所創建的線程的事件隊列。
    • EventRunner 循環從事件隊列中獲取 InnerEvent 事件或者 Runnable 任務。
    • 處理事件或任務:
      • 如果 EventRunner 取出的事件為 InnerEvent 事件,則觸發 EventHandler 的回調方法并觸發 EventHandler 的處理方法,在新線程上處理該事件。
      • 如果 EventRunner 取出的事件為 Runnable 任務,則 EventRunner 直接在新線程上處理 Runnable 任務。
③ 約束和限制
  • 在進行線程間通信的時候,EventHandler 只能和 EventRunner 所創建的線程進行綁定, EventRunner 創建時需要判斷是否創建成功,只有確保獲取的 EventRunner 實例非空時,才可以使用 EventHandler 綁定 EventRunner。
  • 一個 EventHandler 只能同時與一個 EventRunner 綁定,一個 EventRunner 可以同時綁定多個 EventHandler。

二、應用場景

① EventHandler 開發場景
  • EventHandler 的主要功能是將 InnerEvent 事件或者 Runnable 任務投遞到其他的線程進行處理,其使用的場景包括:
    • 開發者需要將 InnerEvent 事件投遞到新的線程,按照優先級和延時進行處理。投遞時,EventHandler 的優先級可在 IMMEDIATE、HIGH、LOW、IDLE 中選擇,并設置合適的 delayTime。
    • 開發者需要將 Runnable 任務投遞到新的線程,并按照優先級和延時進行處理。投遞時,EventHandler 的優先級可在 IMMEDIATE、HIGH、LOW、IDLE 中選擇,并設置合適的 delayTime。
    • 需要在新創建的線程里投遞事件到原線程進行處理。
② EventRunner 工作模式
  • EventRunner 的工作模式可以分為托管模式和手動模式。兩種模式是在調用 EventRunner 的 create() 方法時,通過選擇不同的參數來實現的,默認為托管模式。
    • 托管模式:不需要調用 run() 和 stop() 方法去啟動和停止 EventRunner。當 EventRunner 實例化時,系統調用 run() 來啟動 EventRunner;當 EventRunner 不被引用時,系統調用 stop() 來停止 EventRunner。
    • 手動模式:需要自行調用 EventRunner 的 run() 方法和 stop() 方法來確保線程的啟動和停止。

三、API 說明

① EventHandler
  • EventHandler 的屬性 Priority(優先級):EventRunner 將根據優先級的高低從事件隊列中獲取事件或者 Runnable 任務進行處理。
  • EventHandler 的屬性:
屬性描述
Priority.IMMEDIATE表示事件被立即投遞
Priority.HIGH表示事件先于LOW優先級投遞
Priority.LOW表示事件優于IDLE優先級投遞,事件的默認優先級是LOW
Priority.IDLE表示在沒有其他事件的情況下,才投遞該事件
  • EventHandler 的主要接口:
接口名描述
EventHandler(EventRunner runner)利用已有的EventRunner來創建EventHandler
current()在processEvent回調中,獲取當前的EventHandler
processEvent?(InnerEvent event)回調處理事件,由開發者實現
sendEvent?(InnerEvent event)發送一個事件到事件隊列,延時為0ms, 優先級為LOW
sendEvent?(InnerEvent event, long delayTime)發送一個延時事件到事件隊列,優先級為LOW
sendEvent?(InnerEvent event, long delayTime, EventHandler.Priority priority)發送一個指定優先級的延時事件到事件隊列
sendEvent?(InnerEvent event, EventHandler.Priority priority)發送一個指定優先級的事件到事件隊列,延時為0ms
sendSyncEvent?(InnerEvent event)發送一個同步事件到事件隊列,延時為0ms,優先級為LOW
sendSyncEvent?(InnerEvent event, EventHandler.Priority priority)發送一個指定優先級的同步事件到事件隊列,延時為0ms,優先級不可以是IDLE
postSyncTask?(Runnable task)發送一個Runnable同步任務到事件隊列,延時為0ms, 優先級為LOW
postSyncTask?(Runnable task, EventHandler.Priority priority)發送一個指定優先級的Runnable同步任務到事件隊列,延時為0ms
postTask?(Runnable task)發送一個Runnable任務到事件隊列,延時為0ms,優先級為LOW
postTask?(Runnable task, long delayTime)發送一個Runnable延時任務到事件隊列,優先級為LOW
postTask?(Runnable task, long delayTime, EventHandler.Priority priority)發送一個指定優先級的Runnable延時任務到事件隊列
postTask?(Runnable task, EventHandler.Priority priority)發送一個指定優先級的Runnable任務到事件隊列,延時為0ms
sendTimingEvent(InnerEvent event, long taskTime)發送一個定時事件到隊列,在taskTime時間執行,如果taskTime小于當前時間,立即執行,優先級為LOW
sendTimingEvent(InnerEvent event, long taskTime, EventHandler.Priority priority)發送一個帶優先級的事件到隊列,在taskTime時間執行,如果taskTime小于當前時間,立即執行
postTimingTask(Runnable task, long taskTime)發送一個Runnable任務到隊列,在taskTime時間執行,如果taskTime小于當前時間,立即執行,優先級為LOW
postTimingTask(Runnable task, long taskTime, EventHandler.Priority priority)發送一個帶優先級的Runnable任務到隊列,在taskTime時間執行,如果taskTime小于當前時間,立即執行
removeEvent(int eventId)刪除指定id的事件
removeEvent(int eventId, long param)刪除指定id和param的事件
removeEvent(int eventId, long param, Object object)刪除指定id、param和object的事件
removeAllEvent()刪除該EventHandler的所有事件
getEventName(InnerEvent event)獲取事件的名字
getEventRunner()獲取該EventHandler綁定的EventRunner
isIdle()判斷隊列是否為空
hasInnerEvent(Runnable runnable)根據指定的runnable參數,檢查是否有還未被處理的任務。可以根據不同的入參進行檢查,詳見EventHandler
② EventRunner
  • EventRunner 主要接口:
接口名描述
create?()創建一個擁有新線程的EventRunner
create?(boolean inNewThread)創建一個擁有新線程的EventRunner,inNewThread為true時,EventRunner為托管模式,系統將自動管理該EventRunner;inNewThread為false時,EventRunner為手動模式
create?(String newThreadName)創建一個擁有新線程的EventRunner, 新線程的名字是 newThreadName
current?()獲取當前線程的EventRunner
run?()EventRunner為手動模式時,調用該方法啟動新的線程
stop?()EventRunner為手動模式時,調用該方法停止新的線程
③ InnerEvent
  • InnerEvent 的屬性:
屬性描述
eventId事件的ID, 由開發者定義用來辨別事件
object事件攜帶的Object信息
param事件攜帶的long型數據
  • InnerEvent 的接口:
接口名描述
drop?()釋放一個事件實例
get?()獲得一個事件實例
get?(int eventId)獲得一個指定的eventId的事件實例
get?(int eventId, long param)獲得一個指定的eventId和param的事件實例
get?(int eventId, long param, Object object)獲得一個指定的eventId,param和object的事件實例
get?(int eventId, Object object)獲得一個指定的eventId和object的事件實例
PacMap getPacMap()獲取PacMap,如果沒有,會新建一個
Runnable getTask()獲取Runnable任務
PacMap peekPacMap()獲取PacMap
void setPacMap(PacMap pacMap)設置PacMap

四、線程的通信使用

① EventHandler 投遞 InnerEvent 事件
  • EventHandler 投遞 InnerEvent 事件,并按照優先級和延時進行處理。
  • 創建 EventHandler 的子類,在子類中重寫實現方法 processEvent() 來處理事件:
private static final int EVENT_MESSAGE_NORMAL = 1;private static final int EVENT_MESSAGE_DELAY = 2;private class MyEventHandler extends EventHandler {private MyEventHandler(EventRunner runner) {super(runner);}// 重寫實現processEvent方法@Overridepublic void processEvent(InnerEvent event) {super.processEvent(event);if (event == null) {return;}int eventId = event.eventId;switch (eventId) {case EVENT_MESSAGE_NORMAL:// 待執行的操作,由開發者定義break;case EVENT_MESSAGE_DELAY:// 待執行的操作,由開發者定義break;default:break;}}}
  • 創建 EventRunner,以手動模式為例:
EventRunner runner = EventRunner.create(false);// create()的參數是true時,則為托管模式
  • 創建 EventHandler 子類的實例:
MyEventHandler myHandler = new MyEventHandler(runner);
  • 獲取 InnerEvent 事件:
// 獲取事件實例,其屬性eventId, param, object由開發者確定,代碼中只是示例long param = 0L; Object object = null; InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param, object);InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param, object);
  • 投遞事件,投遞的優先級以 IMMEDIATE 為例,延時選擇 0ms 和 2m:
// 優先級IMMEDIATE,投遞之后立即處理,延時為0ms,該語句等價于同步投遞sendSyncEvent(event1,EventHandler.Priority.IMMEDIATE);myHandler.sendEvent(normalInnerEvent, 0, EventHandler.Priority.IMMEDIATE);myHandler.sendEvent(delayInnerEvent, 2, EventHandler.Priority.IMMEDIATE); // 延時2ms后立即處理
  • 啟動和停止 EventRunner,如果為托管模式,則不需要此步驟:
runner.run();// 待執行操作...runner.stop();// 開發者根據業務需要在適當時機停止EventRunner
② EventHandler 投遞 Runnable 任務
  • EventHandler 投遞 Runnable 任務,并按照優先級和延時進行處理。
  • 創建 EventHandler 的子類,創建 EventRunner,并創建 EventHandler 子類的實例,步驟與 EventHandler 投遞 InnerEvent 場景的前三個步驟相同。
  • 創建 Runnable 任務。
Runnable normalTask = new Runnable() {@Overridepublic void run() {// 待執行的操作,由開發者定義}};Runnable delayTask = new Runnable() {@Overridepublic void run() {// 待執行的操作,由開發者定義}};
  • 投遞 Runnable 任務,投遞的優先級以 IMMEDIATE 為例,延時選擇 0ms 和 2ms。
// 優先級為immediate,延時0ms,該語句等價于同步投遞myHandler.postSyncTask(task1,EventHandler.Priority.IMMEDIATE);myHandler.postTask(normalTask, 0, EventHandler.Priority.IMMEDIATE);myHandler.postTask(delayTask, 2, EventHandler.Priority.IMMEDIATE);// 延時2ms后立即執行
  • 啟動和停止 EventRunner,如果是托管模式,則不需要此步驟:
runner.run();// 待執行操作...runner.stop();// 停止EventRunner
③ 在新創建的線程里投遞事件到原線程
  • EventHandler 從新創建的線程投遞事件到原線程并進行處理。
  • 創建 EventHandler 的子類,在子類中重寫實現方法 processEvent() 來處理事件。
private static final int EVENT_MESSAGE_CROSS_THREAD = 1;private class MyEventHandler extends EventHandler {private MyEventHandler(EventRunner runner) {super(runner);}// 重寫實現processEvent方法@Overridepublic void processEvent(InnerEvent event) {super.processEvent(event);if (event == null) {return;}int eventId = event.eventId;switch (eventId) {case EVENT_MESSAGE_CROSS_THREAD:Object object = event.object;if (object instanceof EventRunner) {// 將原先線程的EventRunner實例投遞給新創建的線程EventRunner runner2 = (EventRunner) object;// 將原先線程的EventRunner實例與新創建的線程的EventHandler綁定EventHandler myHandler2 = new EventHandler(runner2) {@Overridepublic void processEvent(InnerEvent event) {// 需要在原先線程執行的操作}};int eventId2 = 1; long param2 = 0L; Object object2 = null; InnerEvent event2 = InnerEvent.get(eventId2, param2, object2);myHandler2.sendEvent(event2); // 投遞事件到原先的線程}break;default:break;}}}
  • 創建 EventRunner,以手動模式為例:
EventRunner runner = EventRunner.create(false);// create()的參數是true時,則為托管模式
  • 創建 EventHandler 子類的實例:
MyEventHandler myHandler = new MyEventHandler(runner);
  • 獲取 InnerEvent 事件:
// 獲取事件實例,其屬性eventId, param, object由開發者確定,代碼中只是示例long param = 0L; InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
  • 投遞事件,在新線程上直接處理:
// 將與當前線程綁定的EventRunner投遞到與runner創建的新線程中myHandler.sendEvent(event);
  • 啟動和停止 EventRunner,如果是托管模式,則不需要此步驟:
runner.run();// 待執行操作...runner.stop();// 停止EventRunner

五、完整示例

  • 非托管情況:
// 全局:public static final int CODE_DOWNLOAD_FILE1 = 1;public static final int CODE_DOWNLOAD_FILE2 = 2;public static final int CODE_DOWNLOAD_FILE3 = 3;// 線程A:EventRunner runnerA = EventRunner.create(false);runnerA.run(); // run之后一直循環卡在這里,所以需要新建一個線程run// 線程B:// 1.創建類繼承EventHandlerpublic class MyEventHandler extends EventHandler {private MyEventHandler(EventRunner runner) {super(runner);}@Overridepublic void processEvent(InnerEvent event) {super.processEvent(event);if (event == null) {return;}int eventId = event.eventId;switch (eventId) {case CODE_DOWNLOAD_FILE1: {// 待執行的操作,由開發者定義break;}case CODE_DOWNLOAD_FILE2: {// 待執行的操作,由開發者定義break;}case CODE_DOWNLOAD_FILE3: {// 待執行的操作,由開發者定義break;}default:break;}}}// 2.創建MyEventHandler實例MyEventHandler handler = new MyEventHandler(runnerA);// 3.向線程A發送事件handler.sendEvent(CODE_DOWNLOAD_FILE1);handler.sendEvent(CODE_DOWNLOAD_FILE2);handler.sendEvent(CODE_DOWNLOAD_FILE3);// 4.runnerA不再使用后,退出runnerA.stop();
  • 托管情況:
// 全局:public static final int CODE_DOWNLOAD_FILE1 = 1;public static final int CODE_DOWNLOAD_FILE2 = 2;public static final int CODE_DOWNLOAD_FILE3 = 3;// 1.創建EventRunner A:EventRunner runnerA = EventRunner.create("downloadRunner"); // 內部會新建一個線程// 2.創建類繼承EventHandlerpublic class MyEventHandler extends EventHandler {private MyEventHandler(EventRunner runner) {super(runner);}@Overridepublic void processEvent(InnerEvent event) {super.processEvent(event);if (event == null) {return;}int eventId = event.eventId;switch (eventId) {case CODE_DOWNLOAD_FILE1: {// 待執行的操作,由開發者定義break;}case CODE_DOWNLOAD_FILE2: {// 待執行的操作,由開發者定義break;}case CODE_DOWNLOAD_FILE3: {// 待執行的操作,由開發者定義break;}default:break;}}}// 3.創建MyEventHandler實例MyEventHandler handler = new MyEventHandler(runnerA);// 4.向線程A發送事件handler.sendEvent(CODE_DOWNLOAD_FILE1);handler.sendEvent(CODE_DOWNLOAD_FILE2);handler.sendEvent(CODE_DOWNLOAD_FILE3);// 5.runnerA沒有任何對象引入時,線程會自動回收runnerA = null;

總結

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

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

主站蜘蛛池模板: 国产精品无码一区二区三 | 一区二区三区国产在线 | 北条麻妃久久精品 | 免费黄色在线网址 | 亚州男人天堂 | 欧美寡妇性猛交 | 亚洲顶级毛片 | 精品视频在线观看一区 | 日日操天天 | 精品伊人久久 | 美女极度色诱图片www视频 | 国产亚洲欧美在线 | 一本久久久 | 欧美aaa级| 成人午夜影视在线观看 | 日韩美女在线 | 欧美三级视频在线 | 国产午夜在线观看 | 五月天丁香 | 中文字幕免费高清视频 | 亚洲欧洲一区二区在线观看 | 探花系列在线观看 | 前任攻略在线观看免费完整版 | 亚洲天堂免费在线观看视频 | 少妇精品视频一区二区 | 99re最新网址 | 青青青手机视频在线观看 | 日本一区久久 | 黄色一级大片在线免费看国产一 | 国内久久精品视频 | 国产wwww | 久久午夜免费视频 | 成人福利在线观看 | 免费色片网站 | 国产一区麻豆 | 天天色天天干天天色 | 精品一区二区三区免费 | 色悠久久综合 | 欧美成人精品一区二区男人看 | 成人国产精品一区二区 | www欧美视频 | 久久亚洲欧洲 | 天天综合天天添夜夜添狠狠添 | 国产精品骚 | 麻豆影视免费观看 | 国产精品久久久毛片 | www.香蕉网 | 98自拍视频 | 国产三级在线免费观看 | 无码人妻黑人中文字幕 | 婷婷久久伊人 | 久久久999国产 | 国产精品一区二区av日韩在线 | 粗喘呻吟撞击猛烈疯狂 | 自拍视频国产 | 毛片www | 国产精品高潮呻吟 | 日韩高清一级片 | 人人做人人爱人人爽 | 啪啪免费网 | 国产精选av | 国产一av | 小早川怜子久久精品中文字幕 | 天天看天天爽 | 成人欧美精品 | 亚洲人妻电影一区 | 国产日韩在线播放 | 亚洲福利影视 | 内射中出日韩无国产剧情 | 色呦呦免费视频 | 久久久久亚洲AV成人无码国产 | 国产在线1 | 69av视频| 91国内精品久久久 | 3d动漫精品啪啪一区二区竹菊 | 中文字幕av在线播放 | 国产一区二区三区免费看 | 曰韩av| 极品色av影院 | 成人免费视频软件网站 | 久久av色| 偷偷操不一样的久久 | 中国美女一级看片 | 欧美午夜精品久久久久久人妖 | 性五月天 | 天天爽天天爽 | 伊人开心网 | av免费在线观看网站 | 婷婷四房综合激情五月 | 国产免费看黄 | 国产香蕉在线 | 伊人三区 | 国产丝袜一区二区 | 日韩一区欧美一区 | 91精品啪在线观看国产线免费 | 欧美大浪妇猛交饥渴大叫 | 又黄又湿的网站 | 日韩av中文在线观看 | 制服一区二区 |