cas算法是什么_对算法的认识

cas算法是什么_对算法的认识应用原子操作类,例如AtomicInteger,AtomicBoolean …适用于并发量较小,多cpu情况下;Java中有许多线程安全类,比如线程安全的集合类。从Java5开始,在java.util.concurrent包下提供了大量支持高效并发访问的集合接口和实现类。如:ConcurrentMap、ConcurrentLinkedQueue等线程安全集合。引入问题那么问题来了,这些线程安全类的底层是怎么保证线程安全的,你可能会想到是不是使用同步代码锁synchronized?引入概念这些线

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

应用

原子操作类,例如AtomicInteger,AtomicBoolean …
适用于并发量较小,多cpu情况下;
Java中有许多线程安全类,比如线程安全的集合类。从Java5开始,在java.util.concurrent包下提供了大量支持高效并发访问的集合接口和实现类。如:ConcurrentMap、ConcurrentLinkedQueue等线程安全集合。
引入问题
那么问题来了,这些线程安全类的底层是怎么保证线程安全的,你可能会想到是不是使用同步代码锁synchronized?
引入概念
这些线程安全类底层实现使用一种称为CAS的算法,(Compare And Swap)比较交换。其实现方式是基于硬件平台的汇编指令,在intel的CPU中,使用的是cmpxchg指令,也就是说CAS是靠硬件实现的,从而在硬件层面提升效率。
乐观锁,总是认为是线程安全的,不怕别的线程修改变量,如果修改了我就再重新尝试。
悲观锁:总是认为线程不安全,不管什么情况都进行加锁,要是获取锁失败,就阻塞。

优点
这个算法相对synchronized是比较“乐观的”,它不会像synchronized一样,当一个线程访问共享数据的时候,别的线程都在阻塞。synchronized不管是否有线程冲突都会进行加锁。由于CAS是非阻塞的,它死锁问题天生免疫,并且线程间的相互影响也非常小,更重要的是,使用无锁的方式完全没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销,所以它要比锁的方式拥有更优越的性能。

实现思想
在线程开启的时候,会从主存中给每个线程拷贝一个变量副本到线程各自的运行环境中,CAS算法中包含三个参数(V,E,N),V表示要更新的变量(也就是从主存中拷贝过来的值)、E表示预期的值、N表示新值。
在这里插入图片描述

实现过程
假如现在有两个线程t1,t2,,他们各自的运行环境中都有共享变量的副本V1、V2,预期值E1、E2,预期主存中的值还没有被改变,假设现在在并发环境,并且t1先拿到了执行权限,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次发起尝试,然后t1比较预期值E1和主存中的V,发现E1=V,说明预期值是正确的,执行N1=V1+1,并将N1的值传入主存。这时候贮存中的V=21,然后t2又紧接着拿到了执行权,比较E2和主存V的值,由于V已经被t1改为21,所以E2!=V,t2线程将主存中已经改变的值更新到自己的副本中,再发起重试;直到预期值等于主存中的值,说明没有别的线程对旧值进行修改,继续执行代码,退出;

底层原理
CPU实现原理指令有两种方式:

通过总线锁定来保证原子性
总线锁定其实就是处理器使用了总线锁,所谓总线锁就是使用处理器提供的一个 LOCK# 信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该处理器可以独占共享内存。但是该方法成本太大。因此有了下面的方式。

通过缓存锁来保证
所谓缓存锁定是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作写回内存时,处理器不在总线上声言LOCK#信号,而是修改内部地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时,会使缓存行无效。

有两种情况下处理器不会使用缓存锁定:

当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行时,则处理器会调用总总线锁定;
有些处理器不支持缓存锁定,对于Intel486和pentinum处理器,就是锁定的内存区域在处理器的缓存航也会调用总线锁定。
CAS源码分析

以AtomicInteger为例:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Unsafe是CAS的核心类,Java无法直接访问底层操作系统,而是通过本地native方法来访问,尽管如此,JVM还是开了一个后门:Unsafe它提供了硬件级别的原子操作。
在这里插入图片描述
在这里插入图片描述

在底层调用汇编指令cmpxchg指令,这是一条汇编指令,所以CPU一次通过,是原子操作。

CAS缺点

循环时间太长;
只能保证一个共享变量原子操作;
会出现ABA问题;
结论
其实就是拿副本中的预期值与主存中的值作比较,如果相等就继续替换新值,如果不相等就说明主存中的值已经被别的线程修改,就继续重试;

CAS(比较并交换)是CPU指令级的操作,只有一步原子操作,所以非常快。而且CAS避免了请求操作系统来裁定锁的问题,不用麻烦操作系统,直接在CPU内部就搞定了

转载自添加链接描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/168681.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用 Vue + LayUI 做后台管理、RESTful 交互

    使用 Vue + LayUI 做后台管理、RESTful 交互一、前言1、之前使用了React/Angular,使用起来显然是比jQuery好多了,但时隔半年,最近再次深入研究了vue,很惊喜。故以后选择MVC/MVVM框架的话,建议首选vue,主要是其代码结构,清晰简单。2、使用vue+layui了,但layui里边的layui.js模块vue.js冲突,因此放弃使用layui.js,导致很多高级…

    2022年6月25日
    27
  • 不安装cudnn可不可以_cuDNN安装「建议收藏」

    不安装cudnn可不可以_cuDNN安装「建议收藏」这个系列写了好几篇文章,这是相关文章的索引,仅供参考:去年上半年配置了一台GTX1080深度学习主机:深度学习主机攒机小记,然后分别写了两篇深度学习环境配置的文章:深度学习主机环境配置:Ubuntu16.04+NvidiaGTX1080+CUDA8.0和深度学习主机环境配置:Ubuntu16.04+GeForceGTX1080+TensorFlow,得到了很多同学留言,不过这个一年…

    2022年5月6日
    186
  • kotlin与java的区别[通俗易懂]

    kotlin与java的区别[通俗易懂]Kotlin简介:Kotlin是一个基于JVM的新的编程语言,由JetBrains开发。Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。JetBrains,作为目前广受欢迎的JavaIDEIntelliJ的提供商,在Apache许可下已经开源其Kotlin编程语言。Kotlin已正式成为Android官方开发语言。通过上面的简介,我们对Kotlin也有了大概了认知,Kotlin作为新的一种语言,可以运行在JVM上面,那么它

    2022年7月7日
    24
  • Android加密之全盘加密

    Android加密之全盘加密Android加密之全盘加密前言Android的安全性问题一直备受关注,Google在Android系统的安全方面也是一直没有停止过更新,努力做到更加安全的手机移动操作系统。在Android的安全性方面,有很多模块:内核安全性应用安全性应用签名身份验证TrustyTEESELinux加密等等

    2022年5月13日
    45
  • 回归直线方程「建议收藏」

    回归直线方程「建议收藏」回归直线方程线性回归方程的公式一个简单实现代码//************************************//函数名称:GetLineEquationDouble0//函数说明

    2022年8月3日
    8
  • BM3D改进算法

    BM3D改进算法论文名称:CollaborativeFilteringofCorrelatedNoise:ExactTransform-DomainVarianceforImprovedShrinkageandPatchMatching

    2022年6月1日
    34

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号