OpenHarmony worker详解

一,定义

worker是与主线程并行的独立线程。创建Worker的线程被称为宿主线程,Worker工作的线程被称为Worker线程。创建Worker时传入的脚本文件在Worker线程中执行,通常在Worker线程中处理耗时的操作,需要注意的是,Worker中不能直接更新Page。

worker与java中多线程的概念相似,就是开启一个独立线程,在独立线程中处理耗时任务。

对于处理耗时操作且不阻塞主线程起到了重要的作用,并且多个线程并发可以提高CPU和内存的利用率。在实际开发项目经常遇到网络请求、文件读写、大图片加载等相对耗时的操作,如果这些耗时操作都在主线程中处理,就会导致应用UI界面被卡住,无法操作。但需要注意的是:Worker线程中不能直接操作UI,需要通过消息通知UI线程进行更新,类似于android中的Handler机制。

二,worker运行机制

创建Worker的线程称为宿主线程(不一定是主线程,工作线程也支持创建Worker子线程),worker自身的线程称为Worker子线程(或Actor线程,工作线程)。每个worker子线程与宿主线程拥有独立的实例,包含基础设施,对象,代码段等。Worker子线程和宿主线程之间的通信是基于消息传递的,Worker通过序列化机制与宿主线程之间相互通信,完成命令及数据交互。

三,worker注意事项

1,不可以在library里面创建worker,只能在Ability里面创建worker

2,最多开启8个Worker

3,任务时长无限制

4,woker创建后需要手动管理生命周期

5,由于不同线程中上下文对象是不同的,因此worker线程只能使用线程安全的库,例如UI相关的非线程安全库不能使用

6,序列化传输的数据量大小限制为16MB

四,worker使用

1,新建一个worker

2,在ablity下的build-profile.json5里面添加:

java 复制代码
 "buildOption": {
    "sourceOption": {
      "workers": [
        "./src/main/ets/workers/worker.ts"
      ]
    }
  }

3,在worker里面接受主线程消息,处理耗时任务,向主线程发送消息:

javascript 复制代码
import worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker';


var workerPort : ThreadWorkerGlobalScope = worker.workerPort;


function count5(value) {
  return value*5;
}
function count6(value) {
  return value*6;
}


workerPort.onmessage = function(e : MessageEvents) {
  let data = e.data
  try{
    // 根据传输的数据的type选择进行操作
    switch (data.type) {
      case 0:
        setTimeout(() => {
         // 耗时结束后,向宿主线程发送消息
          workerPort.postMessage({ type: 'message', value: count5(data.value) });
        }, 3000);
        break;
      case 1:
        setTimeout(() => {
          // 耗时结束后,向宿主线程发送消息
          workerPort.postMessage({ type: 'message', value: count6(data.value) });
        }, 3000);
        break;
    }
  }
}


workerPort.onmessageerror = function(e : MessageEvents) {
  // Worker对象接收到一条无法被序列化的消息时被调用的事件处理,主线程执行
}

workerPort.onerror = function(e : ErrorEvent) {
  // 属性表示Worker在执行过程中发生异常被调用的事件处理程序,worker线程执行
}

4,主线程发送消息到worker线程,并接受worker线程的消息:

javascript 复制代码
import worker from '@ohos.worker';

@Component
struct WorkerUseView {

  
  @State result:number =0 ;
  wk:worker.ThreadWorker =null

  aboutToAppear(){
    //创建worker线程
    this.wk = new worker.ThreadWorker("entry/ets/worker.ts");
    this.wk.onmessage=function(message){
      let data = message.data;
      this.result =data.value
    }.bind(this)
  }


  aboutToDisappear(){
    //销毁worker线程
    this.wk.terminate();
  }

  build() {
    Column(){
     
      Button('子线程计算90*5 模拟3s')
        .onClick(()=>{
          // 发送消息到worker线程
          this.wk.postMessage({ 'type': 0 ,'value': 90})
        })
        .margin(10)
      Button('子线程计算90*6 模拟3s')
        .onClick(()=>{
          // 发送消息到worker线程
          this.wk.postMessage({ 'type': 1 ,'value': 90})
        })
        .margin(10)
      Text("子线程计算结果:"+this.result)
    }.width("100%").height("100%")
  }
}

五,总结

worker的使用与安卓中hander的使用非常相似,我们可以把长时间的轮询,定时等任务放到worker里面去执行。

相关推荐
free-elcmacom3 分钟前
C++学习<1>程序分区
开发语言·c++
醉颜凉10 分钟前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言
默 语12 分钟前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
Brilliantwxx38 分钟前
【STM32】 I2C_EEPROM_test 工程(实战篇)
开发语言·stm32·单片机·嵌入式硬件·ecmascript
清水白石00843 分钟前
Python 异步编程深度解析:Cancellation 到底是异常还是控制信号?从 asyncio 取消机制到企业级事务设计最佳实践
开发语言·python
kolyle1 小时前
万级 QPS 下的 Token 分发系统架构:从 0 到 1 跑通 AI 时代的“水电煤“
开发语言·人工智能·系统架构·token·qps·极智词元·大模型私有化部署
caoerzhong1 小时前
JeeWMS 开源仓库管理系统 GPL-3.0 合规指南:Java WMS 二次开发前必须弄清的授权边界
java·开发语言·开源·vue
Patrick在香港1 小时前
Python 审计香港开放数据目录:两个端点差 10 倍,只有 9.3% 的资源标了「最后修改时间」
开发语言·数据库·python·数据分析·api·数据治理·开放数据
Sylvia33.2 小时前
火星数据体育API|一站式接入足球篮球电竞等18+项目实时数据
java·开发语言·python·websocket·游戏
Data_Journal2 小时前
使用 AutoScraper 进行网页抓取:分步教程
大数据·开发语言·数据库·python·scrapy