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

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
简介: 本文介绍了华为仓颉语言中的三种常见线程同步机制:原子操作、互斥锁和条件变量。原子操作(如AtomicInt64)确保多线程下的数据访问安全;可重入互斥锁(ReentrantMutex)通过lock()、unlock()和tryLock()方法解决线程竞争问题;Monitor作为内置锁,扩展了wait()、notify()和notifyAll()功能,用于线程间通信。文章通过代码示例详细解析了每种机制的使用场景与注意事项,帮助开发者快速掌握仓颉语言的同步机制,保障多线程程序的安全性。

前言

线程同步机制是多线程下解决线程对共享资源竞争的主要方式,华为仓颉语言提供了三种常见的同步机制用来保证线程同步安全,分别是原子操作,互斥锁和条件变量。本篇文章详细介绍主要仓颉语言解决同步机制的方法,建议点赞收藏!

同步机制

原子操作

和 java 一样,仓颉也支持使用原子操作(Atomic)用来确保多线程下的数据访问安全。主要是提供整数类型,布尔类型和引用类型三种方式。

以整数类型为例,原子变量 Atomic 包括 8 位(AtomicInt8) 至 64 位(AtomicInt64)的整数类型,同时支持基本数据的读写。

  1. 不使用原子操作,在多线程情况下对数据进行累加。
var sum: Int64 = 0
  for (pattern in 1..100) {
         spawn {
          sum += 1               
            }
         }
  sleep(Duration.second*2)
 AppLog.info("Main===${sum}") 
//输出  Main===96
  1. 使用原子变量 AtomicInt64 对数据进行累加。
var sum = AtomicInt64(0)
  for (pattern in 1..100) {
         spawn {
           sum.fetchAdd(1)
            }
         }
  sleep(Duration.second*2)
  AppLog.info("Main===${sum.load()}")
//输出  Main===99

原子操作 Atomic 使用compareAndSwap 用于数据的交换,使用的和 Java 中一样的 CAS 同步机制用于确保在多线程的情况下能够交换成功。

可重入互斥锁

仓颉语言中同样支持使用可重入互斥锁(ReentrantMutex)来解决多线程的同步问题。当一个线程获取到共享变量的锁时,在该线程释放锁之前,其他线程都无法访问该共享变量,直到该线程持有的同步锁释放。

ReentrantMutex 可重入互斥锁主要提供了三个方法 ,分别是 lock(),unlock(),tryLock()。lock()和 unlock()总是成对出现的,及对共享变量加完锁后,等使用结束必须及时释放锁。

lock()和unlock()

还是以在多线程下对数据进行累加操作。

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

ReentrantMutex 作为可重入互斥锁,当已经获取互斥锁的线程再次获取该互斥锁时,可以直接获取。但是该线程获取几次互斥锁就需要释放几次锁。

tryLock()

tryLock 表示线程尝试去获取锁,但是并一定能够获取到。可以通过 tryLock()返回到布尔值判断该线程释放获取到锁,然后调用 unLock 释放锁。

Monitor

Monitor 是一个内置锁,继承于ReentrantMutex 可重入互斥锁。Monitor 不仅可以使用 lock(),unlock(),tryLock() 还提供了 wait(),notify(),notifyAll()三个方法用于解决线程间的数据安全问题,这一点和 java 不同,java 中的 Object 提供了 wait(),notify(),notifyAll()三个方法。而 在仓颉中是单独封装的类。

下面举例说明:

let fun = spawn {
                 monitor.lock()
                 while (flag) {
                 AppLog.info("Main=== thread 1 开始执行")
                 monitor.wait()
                 AppLog.info("Main=== thread 1 执行结束")
                           
                 }
                  monitor.unlock()
                }
   sleep(Duration.second)
   monitor.lock()
   AppLog.info("Main=== 主线程开始执行")
   flag = false                     
   AppLog.info("Main===主线程执行结束")                     
   monitor.notifyAll()                     
   monitor.unlock()                    
  fun.get()      
//输出
// Main=== thread 1 开始执行
// Main=== 主线程开始执行
// Main===主线程执行结束
// Main=== thread 1 执行结束

需要注意的是 monitor 的 wait 和 notify/notifyAll 方法使用之前必须要先获取到锁,即 lock()。

总结

仓颉中的多线程并发安全同步机制十分重要,对于会 Java 的小伙伴来说简单容易上手,但是也有一些需要注意的点,比如 notify 调用前必须要获取到线程锁,用完必须释放否则会导致其他线程无法获取到锁,本篇文章就先讲这些,已经学会了的小伙伴,赶快动手试试吧!。

目录
打赏
0
11
11
0
20
分享
相关文章
HarmonyOSNext 崩溃急救指南:全局监听+同步退出 = 优雅保命!
本文介绍了HarmonyOS Next中Ark Ts的错误管理技巧,通过全局监听和同步退出机制实现应用崩溃保护。涵盖单线程、Promise及主线程卡死监控方案,并提供实战代码与避坑指南,帮助开发者优雅处理异常,保障用户体验。
136 65
《HarmonyOSNext应用崩溃自救指南:零数据丢失的故障恢复黑科技》
本文详解HarmonyOS Next应用崩溃时如何实现零数据丢失的故障恢复机制,涵盖API差异、核心接口与实战代码,助开发者提升App稳定性和用户体验。
145 65
警惕日志采集失败的 6 大经典雷区:从本地管理反模式到 LoongCollector 标准实践
本文探讨了日志管理中的常见反模式及其潜在问题,强调科学的日志管理策略对系统可观测性的重要性。文中分析了6种反模式:copy truncate轮转导致的日志丢失或重复、NAS/OSS存储引发的采集不一致、多进程写入造成的日志混乱、创建文件空洞释放空间的风险、频繁覆盖写带来的数据完整性问题,以及使用vim编辑日志文件导致的重复采集。针对这些问题,文章提供了最佳实践建议,如使用create模式轮转日志、本地磁盘存储、单线程追加写入等方法,以降低日志采集风险,提升系统可靠性。最后总结指出,遵循这些实践可显著提高故障排查效率和系统性能。
283 20
HarmonyOS实战:腾讯IM之聊天列表搭建(一)
本文详细介绍了在鸿蒙系统中实现腾讯IM聊天列表页面的过程。由于腾讯仅提供了接口而无现成UI,需自行开发。文章涵盖需求分析(如删除功能、时间排序、消息更新)、技术实现(展示会话列表、新增会话、删除会话)等内容,并附代码示例。最终实现了类似微信的聊天列表功能,建议点赞收藏以便后续参考。
134 5
HarmonyOS实战:腾讯IM之聊天列表搭建(一)
一文掌握软件分支管理
本文详细介绍了软件分支管理的实践经验,结合具体项目案例,从版本号、分支命名、标签管理到合并策略等方面展开。通过清晰的规则和流程图示,帮助团队避免版本混乱,提升研发效率。强调主干与开发分支的核心作用,同时提醒合理控制分支数量,确保协作顺畅。适用于不同类型的项目,助力团队建立适合自身的版本管理体系。
406 70
一文掌握软件分支管理
Java 学习路线规划及项目案例中的技术栈应用解析
内容包括:**Java 17核心特性**(如sealed class、record)与模块化开发;Spring Boot 3 + Spring Cloud微服务架构,涉及响应式编程(WebFlux)、多数据库持久化(JPA、R2DBC、MongoDB);云原生技术**如Docker、Kubernetes及CI/CD流程;性能优化(GraalVM Native Image、JVM调优);以及前后端分离开发(Vue 3、Spring Boot集成)。通过全栈电商平台项目实战,掌握从后端服务(用户、商品、订单)到前端应用(Vue 3、React Native)的全流程开发。
77 9
【Azure App Service】使用 tcpping 来获取App Service的网络状态并把结果保存到文本文件中
本文针对云服务使用中网络状态抖动的问题,以Azure App Service为例,介绍如何利用其自带的`tcpping`工具检测网络连通性。通过在Windows或Linux版App Service中执行`tcpping`命令,将结果输出至文本文件,分析timeout行数以判断网络抖动的时间点。文章还提供了具体操作步骤、效果图及参考资料,帮助用户高效排查网络问题。
135 48
通义灵码用户说 | 编程智能体+MCP加持,秒查附近蜜雪冰城
通义灵码现已全面支持Qwen3,新增智能体模式,具备自主决策、环境感知、工具使用等能力,可端到端完成编码任务。支持问答、文件编辑、智能体多模式自由切换,结合MCP工具与记忆功能,提升开发效率。AI IDE重构编程流程,让开发更智能高效。
308 20
端午出游高定:通义灵码+高德 MCP 10 分钟定制出游攻略
本文介绍了如何使用通义灵码编程智能体与高德 MCP 2.0 制作北京端午3天旅行攻略页面。首先需下载通义灵码 AI IDE 并获取高德申请的 key,接着通过添加 MCP 服务生成 travel_tips.html 文件,最终在手机端查看已发布上线的攻略。此外还详细说明了利用通义灵码打造专属 MCP 服务的过程,包括开发计划、代码编写、部署及连接服务等步骤,并提供了自由探索的方向及相关资料链接。
505 98

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问