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

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 本文介绍了华为仓颉语言中的三种线程同步机制:MultiConditionMonitor、synchronized和ThreadLocal。MultiConditionMonitor继承自ReentrantMutex,通过条件变量实现复杂线程同步,文中以生产者-消费者模型为例展示了其用法。synchronized关键字自动加解锁,简化了ReentrantMutex的使用。ThreadLocal则通过线程局部存储实现线程隔离。这三种机制分别适用于不同场景,与Java中的同步工具类似,掌握后可以有效解决多线程并发问题。文章包含代码示例和测试结果,清晰地展示了各机制的实现原理和使用方法。

前言

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

目录
相关文章
|
10月前
|
Android开发
HarmonyOS实战:打造极简HEventBus事件通知
本文介绍了在鸿蒙开发中实现类似EventBus的HEventBus工具,支持事件注册、反注册及多处接收等功能,适用于页面间通信。内容包含单例模式实现、事件管理与消息发送机制,适合日常开发使用。
170 1
|
10月前
|
机器学习/深度学习 自然语言处理 安全
ACL 2025 | GALLa:用图结构增强代码大模型,让代码理解更精准!
通过级联多模态架构将代码结构图对齐到大模型表征中
786 69
|
10月前
|
人工智能 移动开发 IDE
AI + 低代码技术揭秘(十):平台实施
VTJ 提供多平台部署支持,涵盖 Web、移动及跨平台环境。通过专用适配器和低代码优化,实现统一开发体验,并支持 Element Plus、Vant UI 等框架,提升开发效率与应用性能。
320 57
|
10月前
|
开发者
HarmonyOS实战:GIF图下载突破5M限制保存到相册
本文介绍了在鸿蒙开发中解决图片下载问题的方法,包括突破5M流限制及识别图片真实格式(如GIF)。通过分段下载和类型判断,有效解决了大图下载失败及格式错误问题,适合开发者参考实践。
291 0
|
10月前
|
XML 文字识别 监控
闲鱼秒拍脚本插件工具,闲鱼自动捡漏低价软件,监控最新发布商品
这是一款名为“星辰闲鱼扫货【支持下单】v2.1”的自动化脚本工具,可实现闲鱼低价商品的监控与自动操作。用户可通过设置最高价
|
11月前
|
Java 开发者
华为仓颉语言初识:结构体struct和类class的异同
华为仓颉语言是一种基于鸿蒙系统的新型编程语言,结合了Java和C的特点,支持与ArkTs互相调用,提升应用性能。本文详细对比了仓颉语言中结构体(struct)和类(class)的区别:struct不支持继承,赋值时为值传递;而class支持单继承、多实现,赋值时为引用传递。两者均支持构造函数及成员访问修饰符,但struct新增internal修饰符限制包内访问。开发者需根据实际需求选择合适的使用场景。
435 3
|
11月前
|
Android开发 开发者
HarmonyOS实战:3秒实现一个自定义轮播图
本文介绍如何在HarmonyOS中快速实现一个自定义轮播图。通过使用Swiper控件,结合LazyForEach懒加载技术提高性能,并实现循环播放、自动播放、自定义播放间隔、横向/竖向轮播及自定义指示器等功能。文章详细解析了技术实现步骤,包括数据源接口的实现和指示器的定制,帮助开发者轻松上手,建议点赞收藏!
381 1
|
11月前
|
Android开发 iOS开发 容器
HarmonyOS实战:快速实现一个上下滚动的广告控件
本文介绍了如何在鸿蒙系统中实现一个支持上下滚动的广告控件。功能包括自动滚动、手动滑动、广告删除、自定义播放间隔等。通过使用 Swiper 组件和相关属性(如 disableSwipe、autoPlay),结合数据源操作与手势支持,可轻松完成开发。相比 Android 和 iOS,鸿蒙实现方式更简洁,满足日常需求。建议点赞收藏并动手实践!
255 0
HarmonyOS实战:快速实现一个上下滚动的广告控件
|
10月前
|
JSON 前端开发 数据挖掘
《仿盒马》app开发技术分享-- 分类模块顶部导航列表(15)
上一节我们实现了购物车商品列表的大部分功能,实现了商品的添加、删除、增减、价格计算等业务,并且都跟云端进行通信。现在我们继续对项目进行改造,这一节我们要改造的内容是分类页,这个页面我们在之前的非端云一体化项目中实现过。现在要改造成端云一体的模式,并且我们的金刚区也要实现分类页的点击联动
160 0
|
10月前
|
存储 数据库
《仿盒马》app开发技术分享-- 购物车功能完善(14)
上一节我们实现了购物车商品列表的状态切换,已添加商品数量的增减,已添加商品滑动删除,已添加商品在选中情况下的价格计算。这一节我们在这些功能的基础上实现云端记录,因为我们现在只有数据的查询是从云端获取的,其他的操作虽然都实现了相对应的功能,但是当我们操作完,关闭app,再打开不会有对应的记录,有的同学可能会说,那我们把数据用首选项或者数据库的形式存储就可以了吧? 那如果我更换了另一个设备那这些添加的数据是不是就又不能使用了?所以我们的每个操作,最好都是提交到云端,这样我们在其他设备,在退出应用,切换账号这些情况下都能很好的保存我们操作后的购物车状态。
179 0