热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CAS的底层剖析

CAS1、什么是CAS?CAS:又叫campareandsetSwapExchange,自旋锁。再增加一个知识点:悲观锁:认为该操作会被别的线程打断;乐观锁:认为该操作不会被别的线

CAS

1、什么是CAS?

CAS:又叫 campare and set/Swap/Exchange,自旋锁。

再增加一个知识点:

悲观锁:认为该操作被别的线程打断;

乐观锁:认为该操作不会被别的线程打断,会消耗CPU资源;

注:悲观锁,各线程在队列里等待,不消耗CPU资源;而乐观锁时,各线程不断轮询,会消耗CPU资源。使用时理论上可通过压测来决定,但是一般情况下,都是直接使用Synchronized来解决数据同步问题,因为Synchronized经过这么长时间的改进,已经得到了很大的优化。

这里我举个例子来说明悲观锁和乐观锁:

顾名思义,悲观锁就很悲观,它总是认为别人会来抢锁;乐观锁就很乐观,总是认为别人不会来抢锁,很文明。

以上厕所为例:

悲观锁上厕所蹲坑,进去后由于害怕别人直接推门而进粗暴地和它抢马桶,于是便进门便插上门栓,以防止别人进来,然后厕所门上红灯亮起表示有人使用。而其他人想要上厕所时看到门上红灯亮起,故在外面排队等着,等里面的人出来以后,下一个再进去。

乐观锁上厕所蹲坑,进去后由于知道大家都很文明,不会粗暴地直接闯入,而是在推门之前会先敲门询问里面是否有人正在使用,所以进入厕所以后并不会锁门,而是直接开始噗噗噗,多好啊,省时间,哈哈哈。但是每一个来上厕所的人都是很急的,虽然大家都很文明,但是人有三急。所以,后来上厕所的人在外面会不断地敲门询问里面的使用者是否使用完毕。

ABA 问题的解决办法:加版本号。如,每改变一次,自身版本号就 加1。而是否对最后结果有影响(是否更新为新值)需要程序员自己判断。

如果程序员觉得没什么影响,只要结果还是A那就行,如果程序员觉得如果有改变,心里膈应,那就不行。

 


2、使用原子类的底层实现原理

以AtomicInteger 为例:

代码如下,为了实现线程安全,我们使用了原子类AtomicInteger ,而且变量增加使用了AtomicInteger 类的类方法 incrementAndGet()。

 接下来我们就对incrementAndGet() 一探究竟。

按住ctrl + 单击该方法,跳转到AtomicInteger.java类中:

 再点进去unsafe.getAndAddInt()方法,跳转到unsafe.class类中:

 这里有一个循环,条件是做一个CAS 操作。再点击进去,找到是当前类的一个native方法。

 这是什么意思呢?native表示这是用C/C++写的底层代码调用。

似乎到这里断了,不过为了一探究竟,我们继续找到了C代码。

在Java里是unsafe类的compareAndSwapInt(),在底层代码里对应的是unsafe.cpp文件中:

  我们观察到第1217行可知:最后调用的是Atomic::cmpxchg()方法,熟悉C/C++的话,就知道,这是stomic.cpp文件中的cmpxchg方法。

再点进去追击:

 可看到第56行是cmpxchg()方法,一路追踪,我们可发现,到最后是到了atomic_linux_x86.inline.cpp文件中。

找到Atomic.cpp文件中的cmpxchg()方法。

 在这里我们看:

在第95行有个LOCK_IF_MP() ,这其实是个宏定义,意思是是否是多核(Multi Processor):

再继续追击,最后,我们知道最终的实现是依靠底层的 lock cmpxchg  指令(CPU级别)。 

虽然我们从代码可知,在多核(CPU)时才加lock,单核(CPU)不加。如:6 核12线程,我们在这里视为12核。故,单核情况下,指的就是自己线程不会打断自己。

cmpxchg 并不是原子性的,保证原子性还是依靠前面的 Lock。所以,我们才说底层代码直接支持CAS,是一把悲观锁,可以是缓存锁,也可以是总线锁。

 

 

 

 

Over......



推荐阅读
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文概述了在GNU/Linux系统中,动态库在链接和运行阶段的搜索路径及其指定方法,包括通过编译时参数、环境变量及系统配置文件等方式来控制动态库的查找路径。 ... [详细]
  • 宝塔面板下启用HTTPS的详细指南
    本文提供了在宝塔面板环境中配置HTTPS的具体步骤,确保您的网站通信更加安全可靠。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 汇总了2023年7月7日最新的网络安全新闻和技术更新,包括最新的漏洞披露、工具发布及安全事件。 ... [详细]
  • 探索Java 11中的ZGC垃圾收集器
    Java 11引入了一种新的垃圾收集器——ZGC,由Oracle公司研发,旨在支持TB级别的内存容量,并保证极低的暂停时间。本文将探讨ZGC的开发背景、技术特点及其潜在的应用前景。 ... [详细]
  • 七大策略降低云上MySQL成本
    在全球经济放缓和通胀压力下,降低云环境中MySQL数据库的运行成本成为企业关注的重点。本文提供了一系列实用技巧,旨在帮助企业有效控制成本,同时保持高效运作。 ... [详细]
  • 在Android应用开发过程中,开发者经常遇到诸如CPU使用率过高、内存泄漏等问题。本文将介绍几种常用的命令及其应用场景,帮助开发者有效定位并解决问题。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • Docker安全策略与管理
    本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • Web动态服务器Python基本实现
    Web动态服务器Python基本实现 ... [详细]
  • 利用Docker部署JupyterHub以支持Python协同开发
    本文介绍了如何通过Docker容器化技术安装和配置JupyterHub,以实现多用户的Python开发环境,特别适合团队协作场景。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
author-avatar
凌波_薇步
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有