华为仓颉语言初识:并发编程之同步机制(下)
前言
华为仓颉语言除了提供原子操作,可重入互斥锁和 Monitor 用来保证多线程并发安全之外,还提供了 MultiConditionMonitor,synchronized 和 ThreadLocal 三种同步机制解决线程间同步问题。本篇文章详细介绍这三种同步机制的作用原理及使用,建议点赞收藏!
同步机制
MultiConditionMonitor
MultiConditionMonitor 继承于可重入互斥锁 ReentrantMutex,并提供了一个 newCondition() 方法用来动态创建条件变量,解决复杂场景下线程间同步问题。 以经典的生产-消费模型为例,看看 MultiConditionMonitor 是怎么实现生产者和消费者的? 1.定义共享资源类,创建两个条件变量 empty 和 full,用来标识 MulticonditionMonitor 的等待和唤醒条件。
class Apple {
let monitor = MultiConditionMonitor()
var count: Int64 = 0
var empty: ConditionID
var full: ConditionID
init() {
count = 0
synchronized(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)
}
}
}
2.测试生产-消费者模型,当一个线程生产一个 apple 后,另一个线程则消费掉苹果,否则当前线程处于等待状态。
spawn {
for (_ in 1..8) {
apple.produceApple()
sleep(Duration.millisecond * 200)
}
}
spawn {
for (_ in 1..8) {
apple.comsumApple()
sleep(Duration.millisecond * 200)
}
}
3.测试结果,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 +=1
mutex.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 的基本使用掌握起来也十分容易,已经学会了的小伙伴,赶快动手试试吧!。
- 0回答
- 0粉丝
- 0关注
- 华为仓颉语言初识:并发编程之同步机制(上)
- 华为仓颉语言初识:并发编程之线程的基本使用
- 华为仓颉语言初识:结构体struct和类class的异同
- HarmonyOS NEXT 小说阅读器应用系列教程之组件生命周期与数据同步机制教程
- 仓颉编程语言学习资源全汇总【坚果派】
- HarmonyNext:鸿蒙系统下的跨设备通信与数据同步技术
- HarmonyNext技术深度解析:ArkTS在鸿蒙系统中的多线程与并发编程实践
- [HarmonyOS] 鸿蒙 初识 ArkUI-X
- 「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
- ArkTS语言简介
- 鸿蒙开发:异步并发操作
- OpenHarmony 并发 taskpool 和 worker
- 实现文件内容数据同步
- 192.HarmonyOS NEXT系列教程之图案锁事件处理机制详解
- 193.HarmonyOS NEXT系列教程之图案锁错误处理机制详解