首页 > 其他分享 >什么是无锁化

什么是无锁化

时间:2023-08-19 14:12:12浏览次数:42  
标签:无锁 CAS 什么 Redis 加锁 线程 无锁化 cmpxchg

无锁简介

无锁分为两大派系:

  1. 乐观派系:它们认为事情总会往好的方向去发展,总是认为坏的情况发生概率特别小,可以无所顾忌的做任何事情.

  2. 悲观派系:它们总会认为发展事态如果不及时控制,以后就无法挽回,即时此种局面不会发生的情况下。

上述两大派系映射到并发编程中就如同加锁与无锁策略,即加锁是一种悲观策略,无锁是一种乐观策略,因为对于加锁的并发程序来说,它们总是认为每次访问共享资源时总会发生冲突,因此必须对每一次数据操作实施加锁策略。

而无锁则总是假设对共享资源的访问没有冲突,线程可以不停执行,无需加锁,无需等待,一旦发现冲突,无锁策略则采用一种称为CAS的技术来保证线程执行的安全性,这项CAS技术就是无锁策略实现的关键。

串行无锁

无锁串行最简单的实现方式可能就是单线程模型了,Redis/Nginx都采用了这种方式。

Redis是单线程仅指Redis服务端的网络IO是单线程的,Redis的集群数据同步,持久化等都是多线程的。

Redis 采用网络IO多路复用技术,来保证在多连接的时候系统的高吞吐量。
多路: 指的是多个socket网络连接;
复用: 指的是复用一个线程。多路复用主要有三种技术:select,poll,epoll。epoll是最新的, 也是目前最好的多路复用技术。

Redis使用的是非阻塞IO、IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。

结构无锁

利用硬件支持的原子操作实现无锁的数据结构,很多语言都提供CAS原子操作,可以用于实现无锁队列。

什么是CAS

CAS全称为Compare And Swap即比较并交换。
CAS有三个操作数,旧值A,新值B,以及需要读取的内存值V,在更新一个变量时,当且仅当A=V相同时,CAS才会将内存值V修改为B,否则什么都不做。

Java里的CAS是通过调用Unsafe类的native方法,再由C调用CPU底层命令实现的。
原子包 java.util.concurrent.atomic(锁自旋)。

前面我们说到CAS操作的原子性是通过硬件来保证,这里作进一步的解释说明。CPU层面上,CAS的比较-写入操作上是通过cmpxchg指令去实现完成的。然而不幸的是,cmpxchg指令并不是一个原子操作。

即可能会发生这样的场景,线程A在执行cmpxchg指令的过程中,发现当前内存值V与预期值E一致,正准备将新值U写入内存,这个时候另外一个线程B打断了线程A的操作,将该变量修改了。显然这个变量发生了线程安全的问题,为此为了保证cmpxchg指令的原子性,不会被打断,需要在cmpxchg指令前添加一个前缀指令lock。通过对cmpxchg指令进行加锁(总线锁或缓存锁)来保证操作的原子性。通常我们会说CAS算法是一个无锁算法,但其实我们可以看到底层依然是加了锁的,只不过这个锁的粒度是很小的。

CAS的优缺点

缺点:

  • CPU开销比较大:虽然CAS算法是非阻塞的,但是如果CAS操作一直不成功不断循环自旋,将会大大浪费CPU资源
  • 只能保证一个共享变量的原子操作,但是对多个共享变量操作时,CAS是无法保证操作的原子性的。
  • ABA问题,可以通过加版本号解决

优点:一般情况下性能优于锁的使用。

图解Redis单线程模型
乐观锁:CAS 算法
不可不说的Java“锁”事

标签:无锁,CAS,什么,Redis,加锁,线程,无锁化,cmpxchg
From: https://www.cnblogs.com/tonyq/p/17642387.html

相关文章

  • 为什么会变成这样呢? #5(常数边权最短路)
    给定一个\(n\)个点\(m\)条边的有边权无向图,其中边权\(w_i\in\{0,1,\dots,k-1\}\),求点\(1\)到各个点的最短路。期望复杂度:\(O((n+m)k)\)0k最短路在经典的Dijkstra算法中,我们使用一个优先队列来维护松弛队列,这样的时间复杂度为\(O((n+m)\logk)\)。现在我们考虑为每种......
  • Spring容器的初始化为什么叫做refresh?
    Spring容器的初始化被称为"refresh"(刷新)的原因是因为它的目标是为容器注入和加载所有的配置信息,并为应用程序准备好可用的bean定义和实例。在此过程中,Spring容器会读取配置文件、解析注解、实例化bean,并建立它们之间的依赖关系。一、Spring容器的初始化Spring容器是一个负责管理b......
  • 为什么CRUD如此重要
    CRUD经常用于与数据库和数据库设计相关的任何事情,如果没有CRUD操作,软件开发人员将无法完成任何事情。另一方面,CRUD对最终用户同样重要,没有它,注册网站、创建博客或书签之类的事情将是不可能的,我们使用的大多数应用程序都允许我们添加或创建新条目、搜索现有条目、对其进行更改......
  • await this.$nextTick()和this.$nextTick(callback)有什么区别?记一次bug调试
    背景需要实现一个需求,一个小区业务详情页面,在左侧菜单栏切换了小区后,详情页跟着切换。这个详情页面是根据url上的/:id来确定小区id的,所以切换了小区后,应该切换路由。于是这样实现:watch:{//监听小区号变化neighNo(newVal){if(newVal){//切换路......
  • 1.什么是会计
    WhatisAccounting?Aninformationsystemthatmeasures,processesandcommunicatesfinancialinformationaboutaneconomicentity.会计学一套信息系统,用来对账务信息进行测量、处理以及沟通。收集商业活动的数据,转为有效的财务信息以供决策者参考。企业目标Profitab......
  • 期货交易的保证金是什么?这么重要吗?FPmarkets示例澳福探讨
    在期货合约交易中,保证金至关重要,但是很多交易者都不明白为什么需要保证金,今天 FPmarkets澳福就和各位投资者探讨一下这个问题,首先,我们需要了解什么是保证金。保证金是启动期货头寸所需的权益,不是信贷或贷款,也不是对资产的支付。保证金是指在期货账户上应拥有的金额,确保投资者有偿......
  • 数字孪生技术与Scada有什么区别?
    虽然SCADA和数字孪生用于工业领域,但它们有不同的用途。SCADA专注于工业过程的实时监测和控制,而数字孪生用于模拟和分析系统的性能。接下来,让我们详细讨论SCADA和数字孪生(SCADA与数字孪生)之间的区别。SCADA与数字孪生的差异SCADA系统专注于工业过程的实时监测和控制,而数字孪生则......
  • 什么是数据结构
    一、数据结构的起源1968年,美国高德纳教授,《计算机程序设计艺术》第一卷《基本算法》提出,开创了数据结构与算法的先河数据结构是一门研究数据之间关系、操作的学科,而非计算数据方法数据结构+算法=程序揭露了程序的本质,沃思凭借这个观点获得了图灵奖二、数据结构中的基本概......
  • 什么情况下数据库表索引会失效?
    什么情况下数据库表索引会失效?1.单独引用复合索引里非第⼀位置的索引列假如有INDEX(a,b,c),当条件为a或a,b或a,b,c时都可以使用索引,但是当条件为b,c时将不会使用索引。复合索引遵守“最左前缀”原则,即在查询条件中使用了复合索引的第⼀个字段,索引才会被使用。因此,在复合索引中索......
  • 深度云化时代,什么样的云网络才是企业的“心头好”?
    科技云报道原创。近年来企业上云的快速推进,对云网络提出了更多需求。最初,云网络只是满足互联网业务公网接入。随着移动互联网的发展,企业对云上网络安全隔离能力和互访能力、企业数据中心与云上网络互联、构建混合云的能力,以及在云上多地域部署业务后的多地域网络互联能力等,都推动着......