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

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 本文介绍了华为仓颉语言中的三种常见线程同步机制:原子操作、互斥锁和条件变量。原子操作(如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 调用前必须要获取到线程锁,用完必须释放否则会导致其他线程无法获取到锁,本篇文章就先讲这些,已经学会了的小伙伴,赶快动手试试吧!。

目录
相关文章
HarmonyOS实战:Tab顶部滑动悬停功能实现
在鸿蒙开发中,实现Scroll嵌套List列表滑动时顶部悬停的效果是一个常见需求。本文详细介绍了如何通过布局和事件处理来实现这一功能。首先,使用Scroll嵌套List和Tab布局来构建基础页面。然后,通过设置nestedScroll属性为NestedScrollMode.PARENT_FIRST,确保外层Scroll优先滑动。接着,通过监听List和Scroll的滑动事件,处理滑动冲突,确保在特定条件下Scroll停止滑动,将滑动事件交给List处理。最终,实现了在上下滑动时优先让Scroll滑动的效果,并提供了扩展思路,如优先让List滑动等。
540 10
HarmonyOS实战:Tab顶部滑动悬停功能实现
|
12月前
|
Java 开发者 Kotlin
华为仓颉语言初识:并发编程之线程的基本使用
本文详细介绍了仓颉语言中线程的基本使用,包括线程创建(通过`spawn`关键字)、线程名称设置、线程执行控制(使用`get`方法阻塞主线程以获取子线程结果)以及线程取消(通过`cancel()`方法)。文章还指出仓颉线程与Java等语言的差异,例如默认不提供线程名称。掌握这些内容有助于开发者高效处理并发任务,提升程序性能。
379 2
|
定位技术 API
HarmonyOS实战:高德地图定位功能完整流程详解
本文详细介绍了在鸿蒙系统中使用高德地图实现完整定位功能的流程。首先分析需求,包括权限申请、检查GPS状态、单次或多次定位选择以及定位失败处理。接着通过代码实现具体步骤:添加定位权限、申请用户权限、检查GPS开关状态、启动定位服务,并处理定位成功或失败的情况。若定位失败,可尝试获取历史定位信息或使用默认位置。最后总结指出,虽然定位功能基础简单,但完整的流程与细节处理才是关键。建议读者动手实践,掌握高德地图定位功能的使用。
1442 15
|
12月前
|
开发工具 开发者
HarmonyOS实战:腾讯IM之聊天详情页面搭建(二)
本文讲解了在鸿蒙系统中实现腾讯IM聊天功能的完整流程,涵盖对话列表展示、历史消息获取、实时消息更新及文本消息发送等核心功能。通过实际代码示例,详细说明了如何利用IM SDK实现聊天业务逻辑。适合开发者逐步学习并实践,建议点赞收藏以便参考。
326 9
HarmonyOS实战:腾讯IM之聊天详情页面搭建(二)
|
11月前
HarmonyOS实战:腾讯IM之消息删除、撤回和重发(三)
本文详细介绍了鸿蒙 IM 聊天中实现消息撤回、删除和重发功能的方法。消息撤回支持在 120 秒内召回自己发送的消息,通过 `revokeMessage` 方法实现;消息删除使用 `deleteMessage` 方法清除本地与云端记录;消息重发则先删除失败消息再重新发送,并处理用户被拉黑的异常情况。结合状态管理,可轻松实现类似微信的功能,建议点赞收藏并动手实践!
561 3
HarmonyOS实战:腾讯IM之消息删除、撤回和重发(三)
|
12月前
|
开发工具 Android开发 iOS开发
HarmonyOS实战:腾讯IM之聊天列表搭建(一)
本文详细介绍了在鸿蒙系统中实现腾讯IM聊天列表页面的过程。由于腾讯仅提供了接口而无现成UI,需自行开发。文章涵盖需求分析(如删除功能、时间排序、消息更新)、技术实现(展示会话列表、新增会话、删除会话)等内容,并附代码示例。最终实现了类似微信的聊天列表功能,建议点赞收藏以便后续参考。
433 5
HarmonyOS实战:腾讯IM之聊天列表搭建(一)
|
定位技术 开发者
HarmonyOS实战:高德地图自定义定位图标展示
本文详细介绍了在鸿蒙系统中实现地图定位功能的开发流程与注意事项。首先,开发者需要申请两个必要的定位权限,并确保用户手动开启系统设置中的位置权限。接着,通过高德定位获取用户位置信息,并使用自定义图标替代默认的定位箭头。文章特别强调了经纬度数据必须为float类型,否则可能导致定位不准确。此外,还需检查系统的GPS定位按钮是否开启,以确保定位功能正常使用。通过本文的指导,开发者可以避免常见的定位问题,顺利完成地图定位功能的开发。
503 2
HarmonyOS实战:高德地图自定义定位图标展示
|
JSON 数据格式
HarmonyOS实战: 城市选择功能的快速实现
本文详细介绍了在开发城市选择功能时,如何处理城市列表中的多音字、按字母顺序排列城市以及将首字母相同的城市分组的技术实现。首先,通过使用pinyin4js库处理多音字,确保每个城市名称的首字母正确。接着,利用Intl.Collator对城市数据进行字母排序。最后,通过遍历和条件判断,将首字母相同的城市分组,并使用ListItemGroup和sticky功能在UI中展示分组结果。文章强调了分组处理的复杂性,并鼓励读者动手实践以加深理解。
292 6
|
12月前
|
Java 开发者
华为仓颉语言初识:结构体struct和类class的异同
华为仓颉语言是一种基于鸿蒙系统的新型编程语言,结合了Java和C的特点,支持与ArkTs互相调用,提升应用性能。本文详细对比了仓颉语言中结构体(struct)和类(class)的区别:struct不支持继承,赋值时为值传递;而class支持单继承、多实现,赋值时为引用传递。两者均支持构造函数及成员访问修饰符,但struct新增internal修饰符限制包内访问。开发者需根据实际需求选择合适的使用场景。
464 3