上一章我们了解了3种处理多线程中共享资源安全的方法,今天我们将更近一步,学习一种针对简单线程同步场景的解决方案——Interlocked。

在此之前我们先学习一个概念——原子操作。

01、原子操作

原子操作,其概念源于化学领域,原子是构成化学元素的普通物质的最小单位;原子也是化学变化中最小的粒子及元素化学性质的最小单位。

借鉴到编程语言中原子操作指:不可分割的操作单元,是指一类不可中断的操作,它在执行时要么全部执行,要么全部不执行,不会被其他操作打断,而执行结果要么全部成功,要不全部失败,没有其他状态。

我们再回忆一下我们学习线程同步的目的——确保多个线程在访问共享资源时能够按顺序、安全地进行操作,从而避免并发执行带来的数据竞争不一致的状态。

可以说原子操作天然的解决了多线程共享资源安全问题。

在C#语言中,Interlocked类提供了一系列可以进行原子操作的工具。

02、Interlocked实现原理

Interlocked的原子操作是基于CPU本身实现,是硬件级别的原子指令封装,并且它不需要显式的线程阻塞,因此比传统的锁机制(如互斥锁、信号量等)效率更高,尤其是在高并发的场景下。

线程阻塞是指操作系统把当前线程从运行状态变更为阻塞状态,并且操作系统会把当前线程占用的CPU时间片分配给其他线程,使当前线程尽可能少的占用CPU时间。在分配CPU时间片时会涉及上下文切换等操作。

因此Interlocked的非阻塞特性,严格意义上来说并不是锁,但是效率却比锁高得多。

另外如果一个方法在CPU层面上被设计为对立不可分割的指令,那么它本质上就是原子的,严格的原子性可以阻止任何抢占的可能。因此在32位CPU中,一个操作数的大小为32位,因此可以提供32位即4个字节大小及以内的数据类型(如int,float)进行读写的原子操作。同理64位CPU,则可以提供64位级8个字节大小及以内的数据类型(如long,double)进行读写的原子操作。

其实在上一章也举个一个例子,在32位CPU环境下操作long类型,多线程情况下会出现线程不完全问题,因为对于32位CPU,操作一次long类型数据至少需要两个原子指令,因此就会出现线程安全问题。

03、Interlocked常用方法

Interlocked方法从.NET Framework 1.1到目前最新的.NET 9也经历了长足的发展和完善。可以总结为:支持的操作类型在增加,操作能力也再增加,由早期的简单递增、递减、替换操作到现在的复杂位操作,内存屏障操作等。

下面我们先整体了解一下Interlocked有那些方法。

  • Read: 原子的读取64位值;

  • Increment: 原子的递增指定的变量,并返回递增后的新值;

  • Decrement: 原子的递减指定的变量,并返回递减后的新值;

  • Add: 原子的对两个变量求和,将第一个变量替换为两者和,并返回操作后第一个变量的新值;

  • Exchange: 原子的交换两个变量,并返回第一个变量的原始值;

  • Exchange: Exchange方法的泛型版本;

  • CompareExchange: 原子的比较第一个变量和第三个变量是否相等,如果相等,则将第一个变量替换为第二个变量值,并返回第一个变量的原始值;

  • CompareExchange: CompareExchange方法的泛型版本;

  • And: 原子的对两个变量进行按位与操作,将第一个变量替换为操作结果,并返回第一个变量的原始值;

  • Or: 原子的对两个变量进行按位或操作,将第一个变量替换为操作结果,并返回第一个变量的原始值;

  • MemoryBarrier: 强制执行内存屏障,作用范围当前线程,无返回值;

  • MemoryBarrierProcessWide: 提供进程范围的内存屏障,确保任何 CPU 的读取和写入无法跨屏障移动;

后面我们将详细讲解每个方法的如何使用。

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner

并发编程 - 线程同步(三)之原子操作Interlocked简介的更多相关文章

  1. Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  2. 33 - 并发编程-线程同步-Event-lock

    目录 1 线程同步 1.1 Event 1.1.1 什么是Flag? 1.1.2 Event原理 1.1.3 吃包子 1.2 Lock 1.2.1 lock方法 1.2.2 计数器 1.2.3 非阻塞 ...

  3. java并发编程笔记(三)——线程安全性

    java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...

  4. 【Java并发基础】并发编程领域的三个问题:分工、同步和互斥

    前言 可以将Java并发编程抽象为三个核心问题:分工.同步和互斥. 这三个问题的产生源自对性能的需求.最初时,为提高计算机的效率,当IO在等待时不让CPU空闲,于是就出现了分时操作系统也就出现了并发. ...

  5. [书籍翻译] 《JavaScript并发编程》第三章 使用Promises实现同步

    本文是我翻译<JavaScript Concurrency>书籍的第三章 使用Promises实现同步,该书主要以Promises.Generator.Web workers等技术来讲解J ...

  6. C#并行编程-线程同步原语

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  7. Java并发编程:同步容器

    Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...

  8. 【转】Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch).今天我们就来讨论下同步容器. ...

  9. 8、Java并发编程:同步容器

    Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...

  10. 并发编程之第三篇(synchronized)

    并发编程之第三篇(synchronized) 3. 自旋优化 4. 偏向锁 撤销-其它线程使用对象 撤销-调用wait/notify 批量重偏向 批量撤销 5. 锁消除 4.7 wait/notify ...

随机推荐

  1. 域渗透之初识Kerberos认证过程

    目录 Kerberos协议中的角色 关键名词 Kerberos协议的工作流程 AS_REQ & AS_REP TGS_REQ & TGS_REP AP_REQ PAC 总结 Kerbe ...

  2. 基于nginx的tomcat负载均衡和集群(超简单)

    今天看到"基于apache的tomcat负载均衡和集群配置 "这篇文章成为javaEye热点. 略看了一下,感觉太复杂,要配置的东西太多,因此在这里写出一种更简洁的方法. 要集群t ...

  3. 【原创】linux实时操作系统xenomai看门狗(watchdog)机制及作用介绍

    版权声明:本文为本文为博主原创文章,转载请注明出处 https://www.cnblogs.com/wsg1100.如有错误,欢迎指正. 目录 一.前言 PREEMPT-RT(RT Throttlin ...

  4. MySQL之sql_mode

    sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式,所以开发.测试环境的数据库也必须要设置,这 ...

  5. Springboot集成WebSocket实现智能聊天【Demo】

    背景 openai 目前越来越流行,其他 ai 产业也随之而来,偶然翻到 openai接口文档,就想着可以调用接口实现智能聊天,接下来就写写我怎么接入 websocket 的过程,文笔不佳,谅解. 接 ...

  6. vue 路由的代码实现(转)

    https://juejin.cn/post/6844904051679870984 需要的使用到的知识 地址变化事件监控 vue插件机制 构造地址和组件的映射关系 定义route-view 组件 当 ...

  7. pdf.js 笔记

    1.介绍 官方文档,pdf.js是由mozilla开源的js库,用于在web环境中渲染和显示pdf文档 目前,绝大多数PC浏览器都已经内置了pdf阅读器,能够直接预览pdf文件(内置了pdf.js), ...

  8. Java基础面试:关键字与注释

    Java 中的关键字 什么是关键字 Java 关键字是 Java 语言中预先定义好的.具有特殊含义的标识符.这些标识符在程序中有固定的用途,不能用作变量名.方法名或类名.Java 中共有 53 个特殊 ...

  9. C# 企业微信消息推送对接,实现天气预报推送

    C# 企业微信消息推送对接,实现天气预报推送 迷恋自留地 准备工作 需要获取的东西1. 企业Id,2.应用secret 和 应用ID 获取企业id 注册完成后,在我的企业=>企业信息=>最 ...

  10. React使用useRef调用子组件方法

    前情 公司前端主技术栈是react系,最近在提取组件的时候想到vue可以通过ref获取子组件,再调用子组件的方法,于是想在react中实现同样效果. 实现原理 父组件调用useRef获取ref对象,再 ...