java的原子类 AtomicInteger 实现原理是什么?
采用硬件提供原子操作指令实现的,即CAS。每次调用都会先判断预期的值是否符合,才进行写操作,保证数据安全。
CAS机制
CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。CAS机制当中使用了3个基本操作数:
(1)内存地址V,也就是AtomicInteger中的valueOffset。
(2)旧的预期值A,也就是getAndIncrement方法中的current。
(3)要修改的新值B,也就是getAndIncrement方法中的next。
CAS机制中,更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。下面我们来看一个具体的例子:
(1)在内存地址V当中,存储着值为10的变量。
(2)此时线程1想要把变量的值增加1。对线程1来说,旧的预期值A=10,要修改的新值B=11。
(3)但是,在线程1要提交更新之前,另一个线程2抢先一步,把内存地址V中的变量值率先更新成了11。
(4)此时,线程1开始提交更新,首先进行A和地址V的实际值比较(Compare),发现A不等于V的实际值,提交失败。
(5)线程1重新获取内存地址V的当前值,并重新计算想要修改的新值。此时对线程1来说,A=11,B=12。这个重新尝试的过程被称为自旋。
(6)这一次比较幸运,没有其他线程改变地址V的值。线程1进行Compare,发现A和地址V的实际值是相等的。
(7)线程1进行替换,把地址V的值替换为B,也就是12。
对比Synchronized,我们可以发现,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么
严重,所以让线程不断去尝试更新。
但是CAS机制通常也存在以下缺点:
(1)ABA问题
如果V的初始值是A,在准备赋值的时候检查到它仍然是A,那么能说它没有改变过吗?也许V经历了这样一个过程:它先变成了B,又变成了A,使用CAS检查时
以为它没变,其实却已经改变过了;则可以加上版本号:1A-2B-3A
(2)CPU开销较大
在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。
(3)不能保证代码块的原子性
CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。
java的原子类 AtomicInteger 实现原理是什么?的更多相关文章
- 对Java原子类AtomicInteger实现原理的一点总结
java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...
- Java原子类AtomicInteger实现原理的一点总结
java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...
- java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4
java 线程 原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...
- Java原子类及内部原理
一.引入 原子是世界上的最小单位,具有不可分割性.比如 a=0:(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作是原子操作.再比如:a++: 这个操作实际是a = a + ...
- (转)Java atomic原子类的使用方法和原理(一)
在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...
- Java并发—原子类,java.util.concurrent.atomic包(转载)
原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...
- juc原子类之二:基本类型原子类AtomicInteger(AtomicLong、AtomicBoolean)
一.AtomicInteger简介 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.以AtomicInteger对基本类型的原子类 ...
- java并发:原子类之AtomicLong
原子类之AtomicLong java线程中的操作,需要满足原子性.可见性等原则,比如i++这样的操作不具备原子性, A线程读取了i,另一个线程执行i++,A线程再执行i++就会引发线程安全问题 推荐 ...
- JUC包-原子类(AtomicInteger为例)
目录 JUC包-原子类 为什么需要JUC包中的原子类 原子类原理(AtomicInteger为例) volatile CAS CAS的缺点 ABA问题 什么是ABA问题 ABA问题的解决办法 JUC包 ...
随机推荐
- Hive数据导入导出的几种方式
一,Hive数据导入的几种方式 首先列出讲述下面几种导入方式的数据和hive表. 导入: 本地文件导入到Hive表: Hive表导入到Hive表; HDFS文件导入到Hive表; 创建表的过程中从其他 ...
- python的导包问题
有事会遇到在python代码中导入包错误问题,本文简单对python包的引入做简单介绍 简单说,我认为python导包一共有3种情况,分别是: 要导的包与当前文件在同一层要导的包在当前文件的底层(就是 ...
- Epic Games工程师分享:如何在移动平台上做UE4的UI优化?
转自:https://blog.csdn.net/debugconsole/article/details/79281290 随着技术的不断升级,高性能的引擎逐渐受到越来越多研发商的青睐,UE4就是其 ...
- EXT.NET 一些用法
EXT.NET 一些用法 <ext:GridPanel ClicksToEdit="1" <%-- 点击几下单元格可编辑 1 代表单击一下.--%> > & ...
- CentOS安装redis.tar.gz
1. # cd /usr/local/src 2. # tar -zxvf redis-3.0.6.tar.gz 3. # cd redis-3.0.6 4.# make 5.# make PREF ...
- HBase核心知识点总结
一.HBase介绍 1.基本概念 HBase是一种Hadoop数据库,经常被描述为一种稀疏的,分布式的,持久化的,多维有序映射,它基于行键.列键和时间戳建立索引,是一个可以随机访问的存储和检索数据的平 ...
- javascript-保留2位小数函数方法
function zero(num){ var str=num.toString(); if(str.indexOf(".")==-1){ return num+'.00'; }e ...
- Hook技术之API拦截(API Hook)
一.实现过程 1.钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统. 2.在消息没有到达目的窗口前,钩子就捕获消息(即钩子函数先得到控制权). 3.钩子可以加工处理该消息,即钩子机制允许应 ...
- Windows把内存变成快速虚拟硬盘
笔记本电脑安装了8G内存,却装了个Win7 32位系统,结果只能识别2946MB内存,还有5GB多内存白白浪费了,那个闹心啊,别提多不爽,听说能把内存虚拟成硬盘使用,用它缓存系统临时文件,以及缓存网页 ...
- 使用vim时生成的.swp文件
1. 在使用vim时,退出编辑后,发现生成了swp文件,如下: 发现用vim打开一个文件时,都会产生一个.swp的隐藏文件(即文件名.开头的),这个文件是一个临时交换文件,用来备份缓冲区中的内容,用于 ...