鸿蒙开发-ArkTS语言-并发

鸿蒙开发-UI-交互事件-键鼠事件

鸿蒙开发-UI-交互事件-焦点事件

鸿蒙开发-UI-交互事件-手势事件

鸿蒙开发-UI-web

鸿蒙开发-UI-web-页面

鸿蒙开发-ArkTS语言-基础类库

文章目录

前言

一、并发概述

二、异步并发开发

1. 异步并发概述

1.1 Promise

1.2 async/await

2. 单次IO任务

三、多线程并发开发

1. 多线程概述

2. TaskPool和Worker

2.1 TaskPool实现特点

2.2 TaskPool使用场景

2.3 TaskPool运行机制

2.4 Worker实现特点

2.5 Worker使用场景以及注意事项

3. @Concurrent

总结


前言

上文简单介绍ArkTS语言基础类库相关概述,简单了解了ArkTS语言提供的基础能力,本文将学习ArkTS语言并发

一、并发概述

并发是指在同一时间段内,能够处理多个任务的能力。为了提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰,HarmonyOS系统提供了异步并发和多线程并发两种处理策略。

二、异步并发开发

1. 异步并发概述

Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开发,例如一次网络请求、一次文件读写等操作。异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等待其完成,而是可以继续执行其他操作

1.1 Promise

Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。

Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。

Promise使用

//setTimeout函数模拟了一个异步操作,并在1秒钟后随机生成一个数字。如果随机数大于0.5,则执行resolve回调函数并将随机数作为参数传递;否则执行reject回调函数并传递一个错误对象作为参数。

//step1:实例化一个Promise对象,同时传入一个带有两个参数(resolve和reject)的函数,resolve和reject分别表示异步操作成功和失败时的回调函数
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve(randomNumber);
    } else {
      reject(new Error('Random number is too small'));
    }
  }, 1000);
});

//step2:Promise对象创建后使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可接受两个参数,一个处理fulfilled状态的函数,另一个处理rejected状态的函数。只传一个参数则表示状态改变就执行,不区分状态结果。使用catch方法注册一个回调函数,用于处理“失败”的结果,即捕获Promise的状态改变为rejected状态或操作失败抛出的异常

promise.then(result => {
  console.info(`Random number is ${result}`);
}).catch(error => {
  console.error(error.message);
});

1.2 async/await

async/await是一种用于处理异步操作的Promise语法糖,使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数,并使用await关键字等待Promise的解析(完成或拒绝),以同步的方式编写异步操作的代码。

async函数是一个返回Promise对象的函数,用于表示一个异步操作。在async函数内部,可以使用await关键字等待一个Promise对象的解析,并返回其解析值。如果一个async函数抛出异常,那么该函数返回的Promise对象将被拒绝,并且异常信息会被传递给Promise对象的onRejected()方法。

代码示例

//模拟了一个异步操作,该操作会在3秒钟后返回一个字符串

async function myAsyncFunction() {
//step1:await关键字来等待Promise对象的解析,并将其解析值存储在result变量中
  const result = await new Promise((resolve) => {
    setTimeout(() => {
      resolve('Hello, world!');
    }, 3000);
  });
  console.info(String(result)); // 输出: Hello, world!
}

myAsyncFunction();

2. 单次IO任务

代码示例

import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';

//step1:定义异步函数实现写文件
async function write(data: string, file: fs.File): Promise<void> {
  fs.write(file.fd, data).then((writeLen: number) => {
    console.info('write data length is: ' + writeLen)
  }).catch((err) => {
    console.error(`Failed to write data. Code is ${err.code}, message is ${err.message}`);
  })
}

//step2:采用异步能力调用step1定义的写文件函数
async function testFunc(): Promise<void> {
  let context = getContext() as common.UIAbilityContext;
  let filePath: string = context.filesDir + "/test.txt"; // 应用文件路径
  let file: fs.File = await fs.open(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  write('Hello World!', file).then(() => {
    console.info('Succeeded in writing data.');
  }).catch((err) => {
    console.error(`Failed to write data. Code is ${err.code}, message is ${err.message}`);
  })
  fs.close(file);
}
testFunc();

三、多线程并发开发

1. 多线程概述

并发模型是用来实现不同应用场景中并发任务的编程模型,常见的并发模型分为基于内存共享的并发模型和基于消息通信的并发模型。Actor并发模型作为基于消息通信并发模型的典型代表,不需要开发者去面对锁带来的一系列复杂偶发的问题,同时并发度也相对较高,因此得到了广泛的支持和使用,也是当前ArkTS语言选择的并发模型。由于Actor模型的内存隔离特性,所以需要进行跨线程的数据序列化传输。

2. TaskPool和Worker

TaskPool(任务池)和Worker的作用是为应用程序提供一个多线程的运行环境,用于处理耗时的计算任务或其他密集型任务。可以有效地避免这些任务阻塞主线程,从而最大化系统的利用率,降低整体资源消耗,并提高系统的整体性能。

2.1 TaskPool实现特点

2.2 TaskPool使用场景

TaskPool偏向独立任务维度,该任务在线程中执行,无需关注线程的生命周期

  

2.3 TaskPool运行机制

TaskPool支持开发者在主线程封装任务抛给任务队列,系统选择合适的工作线程,进行任务的分发及执行,再将结果返回给主线程。接口直观易用,支持任务的执行、取消。工作线程数量上限为4

2.4 Worker实现特点

2.5 Worker使用场景以及注意事项

Worker偏向线程的维度,支持长时间占据线程执行,需要主动管理线程生命周期。

     

 2.6 Worker运行机制

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

3. @Concurrent

在使用TaskPool时,执行的并发函数需要使用该装饰器修饰,否则无法通过相关校验

  


总结

本文详细学习ArkTS语言并发异步并发开发和多线程并发开发两种并发场景,了解了两种并发场景的区别,以及开发方法。同时详细学习了多线程并发开发的两种方式,以及各个使用场景。下文将学习多线程并发开发的示例分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值