写点什么

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

作者:IT小码哥
  • 2025-06-10
    北京
  • 本文字数:1902 字

    阅读完需:约 6 分钟

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

前言

华为仓颉语言除了提供原子操作,可重入互斥锁和 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) } }}
复制代码
  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 1Apple-comsumApple 0Apple-produceApple 1Apple-comsumApple 0Apple-produceApple 1Apple-comsumApple 0Apple-produceApple 1Apple-comsumApple 0Apple-produceApple 1Apple-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 的基本使用掌握起来也十分容易,已经学会了的小伙伴,赶快动手试试吧!。

用户头像

IT小码哥

关注

还未添加个人签名 2021-04-29 加入

还未添加个人简介

评论

发布
暂无评论
华为仓颉语言初识:并发编程之同步机制(下)_鸿蒙_IT小码哥_InfoQ写作社区