HarmonyOS 5.0應用開發——多線程Worker和@Sendable的使用方法

【高心星出品】

文章目錄

      • 多線程Worker和@Sendable的使用方法
        • 開發步驟
        • 運行結果

多線程Worker和@Sendable的使用方法

Worker在HarmonyOS中提供了一種多線程的實現方式,它允許開發者在后臺線程中執行長耗時任務,從而避免阻塞主線程并提高應用的響應性。

@Sendable 注解主要用于標記那些需要在多線程環境中共享的數據對象或函數。被 @Sendable 標記的對象或函數可以在不同的線程之間高效地傳輸數據,這主要得益于 ArkTS 的序列化和反序列化機制。

開發步驟

【案例需求】 接下來要實現一個案例,創建兩個子線程,一個子線程負責數據求和,一個子線程負責數據相減,UI線程提供共享數據給這兩個子線程,子線程運行結果返回給UI線程。

  • 創建兩個worker。

    在ets/下創建一個workers目錄,在該目錄下創建worker。這兩個worker負責接受UI線程傳過來的數據,并且負責子線程運行實體,并將結果發送給UI線程。

在這里插入圖片描述

在這里插入圖片描述

  • addworker的代碼
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import { Temp } from '../pages/Index';const workerPort: ThreadWorkerGlobalScope = worker.workerPort;/*** Defines the event handler to be called when the worker thread receives a message sent by the host thread.* The event handler is executed in the worker thread.** @param event message data*/
// 線程運行實體
function add(temp:Temp){let a=temp.alet b=temp.btemp.a+=5return a+b
}
// 子線程接受UI線程信息并處理
workerPort.onmessage = async (event: MessageEvents) => {if(event){// 模擬線程睡眠2sawait new Promise((resolve:(v:number)=>void)=>{setTimeout(()=>{resolve(10)},2000)})// 解析獲取ui線程發送的數據let t=event.data as Temp// 子線程向UI線程發送消息workerPort.postMessage(add(t))}
};/*** Defines the event handler to be called when the worker receives a message that cannot be deserialized.* The event handler is executed in the worker thread.** @param event message data*/
workerPort.onmessageerror = (event: MessageEvents) => {
};/*** Defines the event handler to be called when an exception occurs during worker execution.* The event handler is executed in the worker thread.** @param event error message*/
workerPort.onerror = (event: ErrorEvent) => {
};
  • jianworker的代碼
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import { Temp } from '../pages/Index';const workerPort: ThreadWorkerGlobalScope = worker.workerPort;/*** Defines the event handler to be called when the worker thread receives a message sent by the host thread.* The event handler is executed in the worker thread.** @param event message data*/
// 線程運行實體
function jian(t:Temp){let a=t.alet b=t.bt.a-=5return Math.abs(a-b)
}
// 子線程接受UI線程的信息 并運行
workerPort.onmessage = async (event: MessageEvents) => {if(event){// 模擬線程睡眠2sawait new Promise((resolve:(v:string)=>void)=>{setTimeout(()=>{resolve('a')},2000)})let t=event.data as Temp// 向UI線程發送消息workerPort.postMessage(jian(t))}
};/*** Defines the event handler to be called when the worker receives a message that cannot be deserialized.* The event handler is executed in the worker thread.** @param event message data*/
workerPort.onmessageerror = (event: MessageEvents) => {
};/*** Defines the event handler to be called when an exception occurs during worker execution.* The event handler is executed in the worker thread.** @param event error message*/
workerPort.onerror = (event: ErrorEvent) => {
};
  • Index.ets代碼
import { MessageEvents, worker } from "@kit.ArkTS";@Sendable
export class Temp {a: numberb: numberconstructor(a: number, b: number) {this.a = a;this.b = b;}
}
@Entry
@Component
struct Index {@State message: string = 'Hello World';// UI線程和其他兩個子線程共享的數據private temp = new Temp(10, 20)//創建了兩個線程private addthread = new worker.ThreadWorker('entry/ets/workers/addworker.ets')private jianthread = new worker.ThreadWorker('entry/ets/workers/jianworker.ets')aboutToAppear(): void {// UI線程中接受兩個子線程發送的信息this.addthread.onmessage = (event: MessageEvents) => {console.log('gxxt add ', event.data as number)console.log('gxxt 當前的temp值: ',JSON.stringify(this.temp))}this.jianthread.onmessage = (event: MessageEvents) => {console.log('gxxt jian ', event.data as number)console.log('gxxt 當前的temp值: ',JSON.stringify(this.temp))}}build() {Column({ space: 20 }) {Button('加線程').width('60%').onClick(() => {this.addthread.postMessageWithSharedSendable(this.temp)})Button('減線程').width('60%').onClick(() => {this.jianthread.postMessageWithSharedSendable(this.temp)})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

項目通過點擊兩個按鈕啟動兩個線程,并將共享數據temp發送給兩個子線程,兩個子線程分別執行相加和相減,同時還更新共享數據的原始值,通過觀察運算結果和共享數據的變化,我們能掌握worker的開發方式。

運行結果
02-28 09:10:59.798   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt add運算結果:  30
02-28 09:10:59.799   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt 當前的temp值:  {"a":15,"b":20}
02-28 09:11:04.877   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt jian運算結果  5
02-28 09:11:04.877   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt 當前的temp值:  {"a":10,"b":20}

剛一開始進行運算的時候add線程面對的a為10,b為20,計算結果為30,add線程同時a=a+5操作,所以此時UI線程得到的a為15;然后jian線程運行結果為|15-20|,jian線程同時a=a-5,所以此時UI線程得到的a為10.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896722.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

避坑!用Docker搞定PHP開發環境搭建(Mac、Docker、Nginx、PHP-FPM、XDebug、PHPStorm、VSCode)

本次更新主要是對環境版本進行了更新,例如php 7.3.7升級到了7.3.8,另外之前的版本有同學踩了坑,主要是官方docker鏡像php:7.3.7-fpm和php:7.3.8-fpm使用了不同版本的debian,后面會提到,請各位同學留意。 因為最近換電腦…

自動化測試開發

4、Servlet模型(一) Servlet的編寫、訪問過程 Servlet簡介 Servlet是Java Servlet的簡稱,是小服務程序或服務連接器,是用Java編寫的服務器端程序,主要功能在于獲取請求,返回響應廣義:一個Ser…

24、Java 集合

十一章:Java 集合 一、集合框架的概述 1、集合:就像一個容器,可以動態的把多個對象的引用放入容器中。簡稱 Java 容器 ? 說明:此時的存儲,主要指的是內存層面的存儲,不涉及到持續化的存儲(.t…

1114棋盤問題acwing(深度優先搜索)

題目描述 在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。 要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對于給定形狀和大小的棋盤,擺放 kk 個棋子的所有可行的擺放…

logback日志輸出配置范例

logback日志輸出配置范例 在wutool中,提供了logback日志輸出配置范例,實現日志文件大小限制、滾動覆蓋策略、定時清理等功能。 關于wutool wutool是一個java代碼片段收集庫,針對特定場景提供輕量解決方案,只要按需選擇代碼片段…

測試人員如何驅動開發?

軟件開發中測試人員的作用正在從傳統的缺陷發現者演變為開發過程的主動推動者。特別是在敏捷和 DevSecOps 環境中,測試人員如何通過參與需求、提供反饋和推動自動化來驅動開發,成為一個值得探討的話題。本文將詳細分析測試人員驅動開發的具體方式&#x…

大模型語料庫的構建過程 包括知識圖譜構建 垂直知識圖譜構建 輸入到sql構建 輸入到cypher構建 通過智能體管理數據生產組件

以下是大模型語料庫的構建過程: 一、文檔切分語料庫構建 數據來源確定: 首先,需要確定語料庫的數據來源。這些來源可以是多種多樣的,包括但不限于: 網絡資源:利用網絡爬蟲技術從各種網站(如新聞…

oracle游標為什么沒有共享,統計一下原因

-- Script Code為什么沒共享 define sql_id bs391f0yq5tpw;set serveroutput onDECLAREv_count number;v_sql varchar2(500);v_sql_id varchar2(30) : &sql_id; BEGINv_sql_id : lower(v_sql_id);dbms_output.put_line(chr(13)||chr(10));dbms_output.put_line(sql_id: ||…

哈希碰撞攻防戰——深入淺出Map/Set的底層實現

各位看官早安午安晚安呀 如果您覺得這篇文章對您有幫助的話 歡迎您一鍵三連,小編盡全力做到更好 歡迎您分享給更多人哦 今天我們來學習Map/Set的底層實現 目錄 問題一:hash會出現負數?數組越界 一:什么是二叉搜索樹&#xff1f…

win10使用haneWIN NFS Server掛載NFS v2服務,u-boot通過NFS下載zImage

1. haneWIN NFS Server掛載NFS v2服務 https://www.hanewin.net/nfs-e.htm netstat -ano | findstr ":2049"TCP 0.0.0.0:2049 0.0.0.0:0 LISTENING 3824UDP 0.0.0.0:2049 *:* 38…

Linux文件系統與目錄結構

Linux系統中一切皆文件 bin 是Binary 的縮寫, 這個目錄存放著最經常使用的命令 boot 這里存放的是啟動Linux時使用的一些核心文件,包括一些連接文件以及鏡像文件,自 己的安裝別放這里。 cdrom 這個目錄通常專門用來掛載光盤。當系統剛安裝時&#x…

一文詳解基于NarrotoAI的短劇短視頻自動解說、混剪AI平臺搭建

背景 前陣給孩子做電子相冊學了點剪輯技術,就想湊個熱鬧剪剪短劇玩玩,一是學以 致用,再者也好奇短劇創作為啥這么火,跟個風。 初步了解情況后,發現我的剪輯技術已經落后了,行家們玩的主要是解說 &#xf…

計算機畢業設計Hadoop+Spark+DeepSeek-R1大模型音樂推薦系統 音樂數據分析 音樂可視化 音樂爬蟲 知識圖譜 大數據畢業設計

溫馨提示:文末有 CSDN 平臺官方提供的學長聯系方式的名片! 溫馨提示:文末有 CSDN 平臺官方提供的學長聯系方式的名片! 溫馨提示:文末有 CSDN 平臺官方提供的學長聯系方式的名片! 作者簡介:Java領…

《Canvas修仙傳·第三重天金丹境(下集)》 ——量子煙花與物理宇宙的混沌法則

各位道友久候!上集我們煉就了《靈蛇奇譚》的元神,今日將開啟Canvas修仙路上最絢麗的篇章——掌控微觀粒子的創世之力!(ノ≧?≦)ノ 章前黑話詞典 🔍 量子境術語表: 對象池(Object Po…

c++ namespace名字域空間

在C中,namespace 是一個非常重要的概念,用于組織代碼,避免名稱沖突。namespace(命名空間)是一個邏輯上的代碼組織單元,用于將代碼(類、函數、變量等)分組,從而避免命名沖…

獲取阿里云OSS預簽名URL下載(java)

1,引入依賴 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId> </dependency> <!--AliSms--> <dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-s…

中間件專欄之Redis篇——Redis的基本IO網絡模型

Redis主要采用的是單線程的事件驅動模型&#xff0c;通過I/O多路復用來實現高效的并發請求處理。 一、單線程模型 Redis 采用 單線程模型 來處理所有請求&#xff0c;包括網絡 I/O 和命令執行。雖然現代多核 CPU 能夠并行處理任務&#xff0c;但 Redis 的設計原則是盡量避免多…

Python 線程同步

Python 線程同步 Python 線程同步 Python 線程同步 線程同步是一種確保兩個或多個線程不同時執行同一塊共享代碼的機制。共享塊中的代碼通常是訪問共享數據或資源&#xff0c;這種共享塊被稱作臨界區。這個概念可以用下面的圖清晰地表示出來&#xff1a; #mermaid-svg-2TivIuc…

Linux操作系統5-進程信號3(信號的捕捉流程,信號集,sigaction)

上篇文章&#xff1a;Linux操作系統5-進程信號3&#xff08;信號的保存, 用戶態與內核態&#xff0c;內核空間&#xff09;-CSDN博客 本篇Gitee倉庫&#xff1a;???????myLerningCode/l26 橘子真甜/Linux操作系統與網絡編程學習 - 碼云 - 開源中國 (gitee.com) 本篇重點…

【機器學習chp10】降維——(核化)PCA + MDS + lsomap + 拉普拉斯特征映射 + t-NSE + UMAP

目錄 一、降維的意義與本質 1、意義 2、本質 3、常見降維方法 &#xff08;1&#xff09;線性降維 &#xff08;2&#xff09;非線性降維 二、基于重構的降維 1、PCA 2、核化PCA &#xff08;1&#xff09;實現過程 步驟一&#xff1a;數據映射與核函數定義 步驟二…