AtomicLong源码解析
一、前言
AtomicLong是作用是对长整形进行原子操作,是java.util.concurrent.atomic包下的一个提供原子操作的Long类型数据的类。在32位操作系统中,64位的long 和 double 变量由于会被JVM当作两个分离的32位来进行操作,所以不具有原子性。而使用AtomicLong能让long的操作保持原子型。
二、源码解析
继承了哪些类
由上图可知AtomicLong继承了Number类和Serializable接口,Serializable接口我想你们应该知道了其作用,但是Number是干什么可能还没有了解。一句话来说明Number类:所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类。
变量说明
//序列化序号,用来对对象进行反序列化时的判断
private static final long serialVersionUID = 1927816293512124184L;
//unsafe常量,设置为使用Unsafe.compareAndSwapInt进行更新
private static final Unsafe unsafe = Unsafe.getUnsafe();
//AtomicLong的值在内存地址的偏移量
private static final long valueOffset;
// 记录底层JVM是否支持无锁比较和交换long。
// 虽然Unsafe.compareAndSwapLong方法在这两种情况下都可以工作
// 但是一些结构应该在Java级别进行处理,以避免锁定用户可见的锁。
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
//AtomicLong当前值
private volatile long value;
valueOffset是如何获取的?
static {try {//获取valueOffset的偏移量valueOffset = unsafe.objectFieldOffset(AtomicLong.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }
}
由源码得知是利用Unsafe类的内部方法进行对“value”获取其内存的偏移地址的,利用static的特性在类加载到内存中就获取到valueOffset的值。
构造方法
AtomicLong类的构造方法只有两个,如下所示:
//使用给定的初始值创建一个新的AtomicLong,即设置当前AtomicLong的值
public AtomicLong(long initialValue) {value = initialValue;
}
//第二个构造方法是默认的构造方法
public AtomicLong() {}
其他方法
① get()方法。
//直接返回变量value
public final long get() {return value;
}
② set(long newValue)方法。
//通过参数newValue将变量value进行值的更新
public final void set(long newValue) {value = newValue;
}
③ lazySet(long newValue) 方法。
//通过unsafe变量最终设置为给定的值。
public final void lazySet(long newValue) {unsafe.putOrderedLong(this, valueOffset, newValue);
}
④ getAndSet(long newValue)方法。
//先获取旧值再更新新值,还是利用unsafe的内部方法来进行操作
public final long getAndSet(long newValue) {return unsafe.getAndSetLong(this, valueOffset, newValue);
}
⑤ compareAndSet(long expect, long update)方法。
//CAS方法,利用判断旧值符合预期值并且更新新的值
public final boolean compareAndSet(long expect, long update) {return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
⑥ getAndIncrement()方法。
//先获取旧值然后再旧值上加一,利用的unsafe内部方法
public final long getAndIncrement() {return unsafe.getAndAddLong(this, valueOffset, 1L);
}
⑦ getAndAdd(long delta)方法。
//先获取旧值然后再旧值上减一,利用的unsafe内部方法
public final long getAndDecrement() {return unsafe.getAndAddLong(this, valueOffset, -1L);
}
当然还有一些其他方法没有写出来,不过其内容都是利用unsafe变量的内部的本地方法进行操作,大家可以自己去了解。
备注:java.util.concurrent.atomic包下是没有AtomicFloat和AtomicDouble这两个方法的,也就是说没有对float和double的原子类操作,因为这两个操作在AtomicLong和AtomicInteger都有两个方法floatValue()和doubleValue(),其源码如下:
//返回float类型的值,利用强制转化
public float floatValue() {return (float)get();
}
//返回double类型的值,利用强制转化
public double doubleValue() {return (double)get();
}
三、总结
- AtomicLong中的内部方法的实现都是利用他的Unsafe变量来进行操作的。
- 大部分的方法都是final的。
AtomicLong源码解析相关推荐
- [Java多线程]-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析
Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...
- 注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ ...
- Java熔断框架有哪些_降级熔断框架 Hystrix 源码解析:滑动窗口统计
降级熔断框架 Hystrix 源码解析:滑动窗口统计 概述 Hystrix 是一个开源的降级熔断框架,用于提高服务可靠性,适用于依赖大量外部服务的业务系统.什么是降级熔断呢? 降级 业务降级,是指牺牲 ...
- dubbo源码解析(十)远程通信——Exchange层
远程通讯--Exchange层 目标:介绍Exchange层的相关设计和逻辑.介绍dubbo-remoting-api中的exchange包内的源码解析. 前言 上一篇文章我讲的是dubbo框架设计中 ...
- Eureka Server源码解析(服务故障下线剔除流程)
原创不易,转载注明出处 系列文章目录 <SpringCloud Eureka Server源码解析(启动流程)> <Eureka Server源码解析(服务注册流程)> < ...
- Java8 ForkJoinPool(一) 源码解析
目录 一.ForkJoinWorkerThread 1.定义 2.run / getPoolIndex 二.InnocuousForkJoinWorkerThread 三.ForkJoinWorker ...
- 深入探究JDK中Timer的使用方式与源码解析
导言 定时器Timer的使用 构造方法 实例方法 使用方式 1. 执行时间晚于当前时间 2. 执行时间早于当前时间 3. 向Timer中添加多个任务 4. 周期性执行任务 5. 停止任务 源码解析 T ...
- 美团Leaf源码——号段模式源码解析
前言 分布式ID生成策略基本要求就是全局不重复,最好还能递增,长度较短,性能高,可用性强.关于相关的实现方案有很多,本文着重使用美团开源的分布式ID生成解决方案--Leaf. 关于Leaf,美团官方的 ...
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
最新文章
- 等号赋值与memcpy的效率问题
- 0基础学python看什么书-零基础学python编程需要看什么书?
- Linux内核创建一个新进程的过程
- MFC Combo-box显示大小
- express运行www后,在http://localhost:3000/查看返回会报 Cannot find module 'jade'
- Show Linux Package Sort By Size
- mess系统可以读取opc服务器,C3. Messages
- project不显示里程碑标志_在Project中设置里程碑
- scala运算符_Scala运算符–算术,关系,逻辑,按位,赋值
- Spring REST实践之HATEOAS
- JAVA——JVM参数设置规则以及参数含义
- pytorch和python一样吗_PyTorch可以和TensorFlow一样快,有时甚至比TensorFlow更快了?...
- 一款好用的取色工具TakeColor.exe
- VMware ESXI7.0的安装与配置(全过程超详细含中英文对照,附应知必会的理论基础和常见故障解决方案)
- IDEA如何创建带有 webapp 目录的 maven 项目
- phpExcel单元格内换行
- iOS第三方库汇总分享
- 笨拙的手指 代码优化版
- 产品经理不再纸上谈兵——雾里看花的用户画像
- 小兵大乱斗服务器维修吗,这个游戏有点意思《小兵大乱斗》最新评测来袭
热门文章
- 北上广工程师手机的必装App,为什么是“它”? | 自由职客
- 00003 不思议迷宫.0009.10:Bug之二:免称号锻造、升级装备,合成卷轴
- 美丽的英文诗句【1】
- 学校计算机老师干什么工作,关于计算机教师的个人工作总结
- android camera录视频教程,Android camera 篇之视频录制
- 一文讲懂SQL分组子句GROUP BY
- 简单了解 VBO,FBO
- 服务器日志显示英文,在闪亮的服务器上显示R控制台日志
- Enscape for SketchUp 创建动画的14个技巧
- 抖音种草短视频可以怎样拍摄?以下几招不可错过