java高并发核心要点|系列3|锁的底层实现原理|ABA问题
继续讲CAS算法,上篇文章我们知道,CAS算法底层实现,是通过CPU的原子指令来实现。
那么这里又有一个情景:
话说,有一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功。
尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。
为什么这样说?我们来想象这样的场景:
在你非常渴的情况下你发现一个盛满水的杯子,你一饮而尽。之后再给杯子里重新倒满水。然后你离开,当杯子的真正主人回来时看到杯子还是盛满水,他当然不知道是否被人喝完重新倒满。这个时候,问题就来了。这杯水已经不是之前的那杯水了。用本山大叔的话来说就是,你大爷还是你大爷,但你大妈已经不是你大妈了!
那么怎么解决这个ABA问题呢?
答案是:版本号。
在这个共享数据区加个版本号,每个线程修改时,都要拿出之前取得的版本号,来进行比较,如果版本号一致,则进行修改,并将版本号+1(当然加多少或减多少都是可以自己定义的)。
实际上,这也是很重要的一个保持数据一致性的设计思想,比如zookeeper,也是用这种机制来保持数据一致性。
为了解决ABA问题,伟大的java为我们提供了AtomicMarkableReference和AtomicStampedReference类。
还是回到上面喝水的例子,如果你是程序员的话,杯子的主人刚好也是你的好基友的话,他会在杯子下放个纸条,上面写上“0”,你喝完水后,把“0”改为“1”,然后你的好基友再回来一看,就知道你已经喝过他的水杯。这时候,他要不要再喝,就很考验你的之间的“基情”了!
下面是演示AtomicStampedReference用法的相关代码:

java高并发核心要点|系列3|锁的底层实现原理|ABA问题的更多相关文章
- java高并发核心要点|系列2|锁的底层实现原理
上篇文章,我们主要讲了解决多线程之间共享数据的核心问题和解决方案,也讲了锁的简单分类. 那么,这把锁,我们应该怎么去实现呢?如果你是java语言设计者,你又会怎么去设计这个线程锁呢? 直觉告诉我们,我 ...
- java高并发核心要点|系列文章
java高并发核心要点|系列1|开篇 java高并发核心要点|系列2|锁的底层实现原理 java高并发核心要点|系列3|锁的底层实现原理|ABA问题 java高并发核心要点|系列4|CPU内存指令重排 ...
- java高并发核心要点|系列1|开篇
在java高并发编程,有几个很重要的内容: 1.CAS算法 2.CPU重排序 3.缓存行伪共享 我们先来说说高并发世界中的主要关键问题是什么? 是数据共享. 因为多线程之间要共享数据,就会遇到各种问题 ...
- java高并发核心要点|系列4|CPU内存指令重排序(Memory Reordering)
今天,我们来学习另一个重要的概念. CPU内存指令重排序(Memory Reordering) 什么叫重排序? 重排序的背景 我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多.当CP ...
- java高并发核心要点|系列5|CPU内存伪共享
上节提到的:伪共享,今天我们来说说. 那什么是伪共享呢? 这得从CPU的缓存结构说起.以下如图,CPU一般来说是有三级缓存,1 级,2级,3级,越上面的,越靠近CPU的,速度越快,成本也越高.也就是说 ...
- 从菜鸟到大神:Java高并发核心编程(连载视频)
任何事情是有套路的,学习是如此, Java的学习,更是如此. 本文,为大家揭示 Java学习的套路 背景 Java高并发.分布式的中间件非常多,网上也有很多组件的源码视频.原理视频,汗牛塞屋了. 作为 ...
- java高并发核心类 AQS(Abstract Queued Synchronizer)抽象队列同步器
什么是AQS? 全称: Abstract Queued Synchronizer: 抽象队列同步器 是 java.util.concurrent.locks包下的一个抽象类 其编写者: Doug Le ...
- Java高并发和多线程系列 - 1. 线程基本概念
1. 什么是线程? 线程和进程的区别 在了解线程的概念前,我们应该先知道什么是进程? 进程是操作系统的基本概念之一, 它是正在执行的程序实例. * 下面的一些进程的基本概念你可以了解下 ------- ...
- 【实战Java高并发程序设计 2】无锁的对象引用:AtomicReference
AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用.也就是它可以保证你在修 ...
随机推荐
- Eureka入门一(了解概念)
Eureka注册中心(8761端口) IDEA(开发工具) 1,创建项目勾选Eureka Server 2, 创建yml文件,拷贝配置,下面配置必须为false,意为,该项目不要作为客户端注册,因为本 ...
- LinkedList简介
原文:https://blog.csdn.net/GongchuangSu/article/details/51527042 LinkedList简介 LinkedList 是一个继承于Abstrac ...
- select框动态添加选项
$.ajax({ url : "${staticServer }/ywgl/zkpzgl/zkfkgl/showBillType.htm", //ajax请求路径 type : & ...
- apache虚拟目录配置实例
apache虚拟目录配置实例 一.首先,开启虚拟主机配置 在文件httpd.conf中找到: include conf/extra/httpd-vhosts.conf #开启 二.对httpd-vho ...
- zabbix日志报错解决
[root@bogon ldap]# cat /tmp/zabbix_server.log 9135:20181204:085433.351 using configuration file: /us ...
- 什么是 go vendor
go vendor 是golang引入管理包依赖的方式,1.5版本开始引进,1.6正式引进. 基本原理其实就是将依赖的包,特指外部包,复制到当前工程下的vendor目录下,这样go build的时候, ...
- 【电子电路技术】短波红外InGaAs探测器简析
核心提示: 红外线是波长介于微波与可见光之间的电磁波,波长在0.75-1000μm之间,其在军事.通讯.探测.医疗等方面有广泛的应用.目前对红外线的分类还没有统一的标准,各个专业根据应用的需要,有着自 ...
- magento下载地址
https://download.magentochina.org/magento/2/ https://www.magentochina.org/blog/download-install-mage ...
- TP5报错Fatal error: require(): Failed opening required '/home/www/xx/public/../thinkphp/start.php
https://jingyan.baidu.com/article/afd8f4deb784fe34e386e97b.html https://www.cnblogs.com/300js/p/9224 ...
- spring boot-2.Hello world
由于 个人习惯,我选择使用STS来作为开发工具.跳过手动构建spring boot 项目的环节,直接使用向导创建spring boot 项目. 1.创建spring boot项目 File ----& ...