当前位置: 首页 > backend >正文

华为仓颉语言初识:并发编程之同步机制(下)

前言

华为仓颉语言除了提供原子操作,可重入互斥锁和 Monitor 用来保证多线程并发安全之外,还提供了 MultiConditionMonitor,synchronized 和 ThreadLocal 三种同步机制解决线程间同步问题。本篇文章详细介绍这三种同步机制的作用原理及使用,建议点赞收藏!

同步机制

MultiConditionMonitor

MultiConditionMonitor 继承于可重入互斥锁 ReentrantMutex,并提供了一个 newCondition() 方法用来动态创建条件变量,解决复杂场景下线程间同步问题。

以经典的生产-消费模型为例,看看 MultiConditionMonitor 是怎么实现生产者和消费者的?

  1. 定义共享资源类,创建两个条件变量 empty 和 full,用来标识 MulticonditionMonitor 的等待和唤醒条件。
class Apple {let monitor = MultiConditionMonitor()var count: Int64 = 0var empty: ConditionIDvar full: ConditionIDinit() {count = 0synchronized(monitor) {empty = monitor.newCondition()full = monitor.newCondition()}}func produceApple() {synchronized(monitor) {while (count == 100) {AppLog.info("Apple-produceApple wait")monitor.wait(empty)}count++AppLog.info("Apple-produceApple ${count}")monitor.notify(full)}}func comsumApple() {synchronized(monitor) {while (count == 0) {AppLog.info("Apple-comsumApple wait")monitor.wait(full)}count--;AppLog.info("Apple-comsumApple ${count}")monitor.notify(empty)}}
}
  1. 测试生产-消费者模型,当一个线程生产一个 apple 后,另一个线程则消费掉苹果,否则当前线程处于等待状态。
  spawn {for (_ in 1..8) {apple.produceApple()sleep(Duration.millisecond * 200) }}spawn {for (_ in 1..8) {apple.comsumApple()sleep(Duration.millisecond * 200) }}
  1. 测试结果,Apple 的生产与消费交替执行。
Apple-produceApple 1
Apple-comsumApple 0
Apple-produceApple 1
Apple-comsumApple 0
Apple-produceApple 1
Apple-comsumApple 0
Apple-produceApple 1
Apple-comsumApple 0
Apple-produceApple 1
Apple-comsumApple 0

synchronized

synchronized 关键字对于大家来说肯定不陌生,在 java 中,synchronized 用来给共享变量进行加锁确保多线程下对共享变量的访问安全。而在仓颉语言中,synchronized 通常和 ReentrantMutex()一起使用,用来自动加解锁。

不使用 synchronized 时,需要手动调用 lock()和 unlock()方法。

 var sum = AtomicInt64(0)let mutex =  ReentrantMutex()for (pattern in 1..100) {spawn {mutex.lock()sum +=1mutex.unlock()}}sleep(Duration.second*2)AppLog.info("Main===${sum}")

使用 synchronized 后,不需要手动调用lock()和 unlock()方法。

 var sum = AtomicInt64(0)let mutex =  ReentrantMutex()for (pattern in 1..100) {spawn {synchroized(mutex){sum +=1}}}sleep(Duration.second*2)AppLog.info("Main===${sum}")

ThreadLocal

线程局部变量 ThreadLocal 的作用在仓颉与 Java 中基本相同,都是将数据保存在线程内部存储空间来保存局部变量,使不同的线程间能够安全的访问自己的局部变量,做到线程隔离的作用。

  let threadLocal = ThreadLocal<Int64>()let fun1 =  spawn {this.threadLocal.set(100)AppLog.info("线程1 === ${this.threadLocal.get().getOrThrow()}")}
let fun2=  spawn {this.threadLocal.set(200)AppLog.info("线程2 === ${this.threadLocal.get().getOrThrow()}")}//输出线程1 === 100线程2 === 200

总结

仓颉语言中的一共提供了 6 种并发工具,用来解决多线程下的并发安全问题。本篇文章讲述最后的三种并发工具,使用和理解上都和 java 基本相似,特别是synchroized 和 ThreadLocal 的基本使用掌握起来也十分容易,已经学会了的小伙伴,赶快动手试试吧!。

http://www.xdnf.cn/news/13355.html

相关文章:

  • 分布式ID最新最佳实践?UUIDv7介绍
  • 进程间通信详解(二):System V IPC 三件套全面解析
  • API网关是什么?原理、功能与架构应用全解析
  • 单位的oa系统能不能在家电脑登陆?办公网址在手机上怎么访问?
  • 如何xml序列化 和反序列化类中包含的类
  • tomcat的websocket协议升级。如何从报文交换变成全双工通信?session对象的注册和绑定?
  • nginx配置中有无‘‘/’’的区别
  • mybatis 关联映射---一对一关联映射
  • LAMP-Cloud与RuoYi-Cloud技术架构对比
  • 大模型驱动的具身智能: 发展与挑战--综述--中国电信人工智能研究院--2024.8.29
  • 风中低语:Linux 信号处理的艺术与实践
  • 新一代 Rust Web 框架的高性能之选
  • 利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
  • ubuntu-root密码遗忘重设方法
  • 校验枚举类类型的入参合法性的统一方案
  • 基于算法竞赛的c++编程(28)结构体的进阶应用
  • DP 1.4 to HDMI 2.1 (DSC) ,8k@60Hz
  • 【WebRTC-14】webrtc是如何创建视频的软/硬编码器?
  • AR 珠宝佩戴,突破传统的购物新体验​
  • visual studio 2022更改主题为深色
  • 学校招生小程序源码介绍
  • Web安全漏洞详解及解决方案
  • LarkXR 赋能AI x XR数字供应链:引领智能设计、数字孪生与零售新未来
  • Android 中使用 OkHttp 创建多个 Client
  • NLP学习路线图(三十七): 问答系统
  • 数据工程全景指南:从基础概念到最佳实践
  • 多面体编译,具体操作模式
  • 使用 origin -> master 强制覆盖本地 master
  • 蜗牛TV_PTV-8608_GK6323V100A-原机备份
  • Everything配置优化指南:打造最快文件搜索工具