OpenHarmony源码转换器—多线程特性转换

本文讨论了如何将多线程的 Java 代码转换为 OpenHarmony ArkTS 代码​

一、简介

Java 内存共享模型

以下示例伪代码和示意图展示了如何使用内存共享模型解决生产者消费者问题。

在这里插入图片描述

生产者消费者与共享内存间交互示意图

为了避免不同生产者或消费者同时访问一块共享内存的容器时产生的脏读,脏写现象,同一时间只能有一个生产者或消费者访问该容器,也就是不同生产者和消费者争夺使用容器的锁。当一个角色获取锁之后其他角色需要等待该角色释放锁之后才能重新尝试获取锁以访问该容器。

// 此段示例为伪代码仅作为逻辑示意,便于开发者理解使用内存共享模型和Actor模型的区别
BufferQueue {
    Queue queue
    Mutex mutex
    add(value) {
        // 尝试获取锁
        if (mutex.lock()) {
            queue.push(value)
            mutex.unlock()
        }
    }

    take() {
        // 尝试获取锁
        if (mutex.lock()) {
            if (queue.empty()) {
                return null
            }
            let res = queue.pop(value)
            mutex.unlock()
            return res
        }
    }
}

// 构造一段全局共享的内存
let g_bufferQueue = new BufferQueue()

Producer {
    run() {
        let value = random()
        // 跨线程访问bufferQueue对象
        g_bufferQueue.add(value)
    }
}

Consumer {
    run() {
        // 跨线程访问bufferQueue对象
        let res = g_bufferQueue.take()
        if (res != null) {
            // 添加消费逻辑
        }
    }
}

Main() {
    let consumer = new Consumer()
    let producer = new Producer()
    // 多线程执行生产任务
    for 0 in 10 :
        let thread = new Thread()
        thread.run(producer.run())
        consumer.run()
}

ArkTS Actor 模型

以下示例简单展示了如何使用基于Actor模型的TaskPool并发能力来解决生产者消费者问题。

Actor模型线程间通信示意图
在这里插入图片描述

Actor模型不同角色之间并不共享内存,生产者线程和UI线程都有自己独占的内存。生产者生产出结果后通过序列化通信将结果发送给UI线程,UI线程消费结果后再发送新的生产任务给生产者线程。

import taskpool from '@ohos.taskpool';
// 跨线程并发任务
@Concurrent
async function produce(): Promise<number>{
  // 添加生产相关逻辑
  console.log("producing...");
  return Math.random();
}

class Consumer {
  public consume(value : number) {
    // 添加消费相关逻辑
    console.log("consuming value: " + value);
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button() {
          Text("start")
        }.onClick(() => {
          let produceTask: taskpool.Task = new taskpool.Task(produce);
          let consumer: Consumer = new Consumer();
          for (let index: number = 0; index < 10; index++) {
            // 执行生产异步并发任务
            taskpool.execute(produceTask).then((res : number) => {
              consumer.consume(res);
            }).catch((e : Error) => {
              console.error(e.message);
            })
          }
        })
        .width('20%')
        .height('20%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

Java 开发者仍然习惯于使用基于共享内存的并发模型,上手 actor 并发模型仍有一定的学习成本,但是借助 OpenHarmony源码转换器,Java 开发者可以无痛将代码迁移到 ArkTS,减轻工作负担。

二、方案对比

Java 开发者在处理并发问题时经常会碰到三个问题:可见性、原子性、有序性,好在都有解决方案,比如用锁来保证可见性,原子指令保证原子性,内存屏障保证有序性。正确使用时,并发粒度高,但出现问题时,很难调试复现。

ArkTS 并发模型不基于共享内存,因此并不会存在上述并发法问题,但并发粒度比较低。

OpenHarmony 实际上提供了两种线程机制:TaskPool、Worker。TaskPool 是对 Worker 的封装,开发者不需要去手动管理生命周期。Worker 线程机制最多开启 8 个线程。

TaskPool运作机制

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

Worker运作机制

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

三、ArkTS 线程当前支持的通信方式

可序列化数据

对于可序列化的数据能够通过Structured Clone算法在线程间进行复制传输。支持的可序列化对象有限:除Symbol之外的基础类型、DateString、RegExp、Array、MapSet、Object (仅限简单对象,比如通过{}或者new Object创建,普通对象仅支持传递属性,不支持传递其原型及方法)、TypedArray。

可转移数据 ArrayBuffer

可转移对象(Transferable object)传输采用地址转移进行序列化,不需要内容拷贝,会将ArrayBuffer的所有权转移给接收该ArrayBuffer的线程,转移后该ArrayBuffer在发送它的线程中变为不可用,不允许再访问
let buffer = new ArrayBuffer(100)

可共享数据 SharedArrayBuffer

共享对象SharedArrayBuffer,拥有固定长度,可以存储任何类型的数据,包括数字、字符串等。

共享对象传输指SharedArrayBuffer支持在多线程之间传递,传递之后的SharedArrayBuffer对象和原始的SharedArrayBuffer对象可以指向同一块内存,进而达到内存共享的目的。

SharedArrayBuffer对象存储的数据在同时被修改时,需要通过原子操作保证其同步性,即下个操作开始之前务必需要等到上个操作已经结束。

let ia = new SharedArrayBuffer(1024): // 定义可共享对象,可以使用Atomics进行操作
ia[37] = 163;
console.log(ia[37]);  // Prints 163, the 38th prime
Atomics.store(ia, 37, 123);
while (Atomics.load(ia, 37) == 163);
console.log(ia[37]);  // Prints 123

四、实现难点

需要考虑到Java如下常用能力

  1. Java线程对共享内存的竞争,例如锁的使用
  2. Java线程之间的同步,例如生产与消费者模型
  3. Java线程之间的协同,例如线程的睡眠、唤醒。
  4. Java synchronize关键字的使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/289567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通信网络(3)——DHCP Snooping

一、简介 前面一节介绍的DAI技术是基于DHCP Snooping绑定表的&#xff0c;因此本篇文章用于介绍何为DHCP Snooping&#xff0c;它是如何生成绑定表的 二、DHCP Snooping诞生背景 由于DHCP报文和ARP报文一样没有认证机制&#xff0c;因此和ARP报文一样&#xff0c;别人给我什…

Java基础-----集合类(四)

文章目录 1. Iterator和ListIterator1.1 简介1.2 常用方法 2. remove方法2.1 比较foreach方式和迭代器方式删除元素2.2 找原因 -- 迭代器删除操作源码 1. Iterator和ListIterator 1.1 简介 1.Iterator 可以遍历List集合&#xff0c;也可以遍历Set集合&#xff1b; ListIterat…

Linux学习(9)——RAID与服务器的常见故障

目录 一、服务器常见故障 1、系统不停重启进入不了系统 2、卡在开机界面右下角有fA B2 H8 3、系统安装不上 4、如何进入服务器的bios 5、一般进入阵列卡的快捷键 6.网络不通 7.硬盘不识别 二、RAID相关知识 1、RAID的概念 2、RAID功能实现 3、RAID实现的方式 三、…

2024年01月数据库流行度最新排名

点击查看最新数据库流行度最新排名&#xff08;每月更新&#xff09; 2024年01月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多&#xff0c;这个数据库就被认为越受欢迎。这是一个领先指标。原始数…

2020年认证杯SPSSPRO杯数学建模C题(第一阶段)抗击疫情,我们能做什么全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 C题 抗击疫情&#xff0c;我们能做什么 原题再现&#xff1a; 2020 年 3 月 12 日&#xff0c;世界卫生组织&#xff08;WHO&#xff09;宣布&#xff0c;席卷全球的冠状病毒引发的病毒性肺炎&#xff08;COVID-19&#xff09;是一种大流行病。…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

51单片机项目(27)——基于51单片机的智能门窗设计

1.功能设计 使用普中51单片机&#xff0c;门窗有自动模式和手动模式。 手动模式下&#xff0c;LCD1602显示屏上显示“manu mode”&#xff0c;通过红外遥控器&#xff0c;控制门窗的开关。其中&#xff0c;按键0代表开窗&#xff0c;按键1代表关窗。&#xff08;使用风扇模拟门…

【Vue2+3入门到实战】(17)VUE之VueCli脚手架自定认创建项目、ESlint代码规范与修复、 ESlint自动修正插件的使用 详细示例

目录 一、本节内容二、VueCli 自定义创建项目三、ESlint代码规范及手动修复1.JavaScript Standard Style 规范说明2.代码规范错误3.手动修正 四、通过eslint插件来实现自动修正 一、本节内容 VueCli脚手架自定认创建项目ESlint代码规范与修复ESlint自动修正插件 二、VueCli 自…

qt 异常汇总

1. C2338 No Q_OBJECT in the class with the signal (编译源文件 ..\..\qt\labelme-master\src\mainwindow.cpp mainwindow头文件中的类没有Q_OBJECT宏定义&#xff0c;或者其子类或者其他依赖没有Q_OBJECT宏定义。 全部qt类都要写上Q_OBJECT. 2. C2385 对connect的访…

uniapp中组件库的Checkbox 复选框 的丰富使用方法

目录 #平台差异说明 #基本使用 #自定义形状 #禁用checkbox #自定义形状 #自定义颜色 #横向排列形式 #横向两端排列形式 API #Checkbox Props #CheckboxGroup Props #CheckboxGroup Event 复选框组件一般用于需要多个选择的场景&#xff0c;该组件功能完整&#xff…

【Github】如何创建一个自己的仓库

一、创建Github账户 不多赘述&#xff0c;进入官网创建账户即可 二、进入个人主页&#xff0c;点击新建仓库 三、按照需求配置仓库信息&#xff0c;点击创建 四、通过git导入代码到仓库 流程大致如下&#xff1a; 1.进入要上传代码的地方&#xff0c;选择打开git命令行界面 2…

DNS主从服务器、转发(缓存)服务器

一、主从服务器 1、基本含义 DNS辅助服务器是一种容错设计&#xff0c;考虑的是一旦DNS主服务器出现故障或因负载太重无法及时响应客户机请求&#xff0c;辅助服务器将挺身而出为主服务器排忧解难。辅助服务器的区域数据都是从主服务器复制而来&#xff0c;因此辅助服务器的数…

Ubuntu软件和vmware下载

https://cn.ubuntu.com/download/desktop VMware 中国 - 交付面向企业的数字化基础 | CN

漏洞复现-天融信TOPSEC static_convert 远程命令执行漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

【Week-P4】CNN猴痘病识别

文章目录 一、环境配置二、准备数据三、搭建网络结构四、开始训练五、查看训练结果六、总结2.3 ⭐torch.utils.data.DataLoader()参数详解6.1 print()常用的三种输出格式6.2 修改网络结构6.2.1 增加池化、卷积和bn层6.2.2 增加卷积、bn、卷积、bn &#x1f368; 本文为&#x1…

界面控件DevExpress Blazor Grid v23.2 - 支持全新的单元格编辑模式

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 在这篇文章中&#xff0c;我们将介…

Navicat 技术干货 | 如何查看关系型数据库(MySQL、PostgreSQL、SQL Server、 Oracle)查询的运行时间

在数据库优化中&#xff0c;理解和监控查询运行时间是至关重要的。无论你是数据库管理员、开发人员或是参与性能调优的人员&#xff0c;知道如何查看查询运行时间能为你的数据库操作提供有价值的参考。本文中&#xff0c;我们将探索几款热门的关系数据库&#xff08;如 MySQL、…

❀记忆冒泡、选择和插入排序算法思想在bash里运用❀

目录 冒泡排序算法:) 选择排序算法:) 插入排序算法:) 冒泡排序算法:) 思想&#xff1a;依次比较相邻两个元素&#xff0c;重复的进行直到没有相邻元素需要交换&#xff0c;排序完成。 #!/bin/bash arr(12 324 543 213 65 64 1 3 45) #定义一个数组 n${#arr[*]} #获取数组…

DHTMLX Spreadsheet v5.1.1 Crack

DHTMLX Spreadsheet 5.1 具有新主题、简化的数字格式本地化、与框架的实时集成演示等 推出 DHTMLX Spreadsheet v5.1。新版本提供了一组有用的功能&#xff0c;这对开发人员和最终用户都有吸引力。 首先&#xff0c;新的电子表格版本提供了 4 个内置主题&#xff0c;可以根据您…

【完整代码】网上书店信息管理系统--基于Mysql数据库与java

网上书店信息管理系统 一、需求分析&#xff08;一&#xff09;设计系统的意义以及用途&#xff08;二&#xff09;实现的功能1.用户模块&#xff1a;1、全部图书浏览2、图书搜索3、购物车管理和订单查看4、修改密码 2.书店管理员模块1、图书类别管理2、图书管理3、全部订单查看…