一、前言

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();
}

三、总结

  1. AtomicLong中的内部方法的实现都是利用他的Unsafe变量来进行操作的。
  2. 大部分的方法都是final的。

AtomicLong源码解析相关推荐

  1. [Java多线程]-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析

    Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...

  2. 注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ ...

  3. Java熔断框架有哪些_降级熔断框架 Hystrix 源码解析:滑动窗口统计

    降级熔断框架 Hystrix 源码解析:滑动窗口统计 概述 Hystrix 是一个开源的降级熔断框架,用于提高服务可靠性,适用于依赖大量外部服务的业务系统.什么是降级熔断呢? 降级 业务降级,是指牺牲 ...

  4. dubbo源码解析(十)远程通信——Exchange层

    远程通讯--Exchange层 目标:介绍Exchange层的相关设计和逻辑.介绍dubbo-remoting-api中的exchange包内的源码解析. 前言 上一篇文章我讲的是dubbo框架设计中 ...

  5. Eureka Server源码解析(服务故障下线剔除流程)

    原创不易,转载注明出处 系列文章目录 <SpringCloud Eureka Server源码解析(启动流程)> <Eureka Server源码解析(服务注册流程)> < ...

  6. Java8 ForkJoinPool(一) 源码解析

    目录 一.ForkJoinWorkerThread 1.定义 2.run / getPoolIndex 二.InnocuousForkJoinWorkerThread 三.ForkJoinWorker ...

  7. 深入探究JDK中Timer的使用方式与源码解析

    导言 定时器Timer的使用 构造方法 实例方法 使用方式 1. 执行时间晚于当前时间 2. 执行时间早于当前时间 3. 向Timer中添加多个任务 4. 周期性执行任务 5. 停止任务 源码解析 T ...

  8. 美团Leaf源码——号段模式源码解析

    前言 分布式ID生成策略基本要求就是全局不重复,最好还能递增,长度较短,性能高,可用性强.关于相关的实现方案有很多,本文着重使用美团开源的分布式ID生成解决方案--Leaf. 关于Leaf,美团官方的 ...

  9. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

最新文章

  1. 等号赋值与memcpy的效率问题
  2. 0基础学python看什么书-零基础学python编程需要看什么书?
  3. Linux内核创建一个新进程的过程
  4. MFC Combo-box显示大小
  5. express运行www后,在http://localhost:3000/查看返回会报 Cannot find module 'jade'
  6. Show Linux Package Sort By Size
  7. mess系统可以读取opc服务器,C3. Messages
  8. project不显示里程碑标志_在Project中设置里程碑
  9. scala运算符_Scala运算符–算术,关系,逻辑,按位,赋值
  10. Spring REST实践之HATEOAS
  11. JAVA——JVM参数设置规则以及参数含义
  12. pytorch和python一样吗_PyTorch可以和TensorFlow一样快,有时甚至比TensorFlow更快了?...
  13. 一款好用的取色工具TakeColor.exe
  14. VMware ESXI7.0的安装与配置(全过程超详细含中英文对照,附应知必会的理论基础和常见故障解决方案)
  15. IDEA如何创建带有 webapp 目录的 maven 项目
  16. phpExcel单元格内换行
  17. iOS第三方库汇总分享
  18. 笨拙的手指 代码优化版
  19. 产品经理不再纸上谈兵——雾里看花的用户画像
  20. 小兵大乱斗服务器维修吗,这个游戏有点意思《小兵大乱斗》最新评测来袭

热门文章

  1. 北上广工程师手机的必装App,为什么是“它”? | 自由职客
  2. 00003 不思议迷宫.0009.10:Bug之二:免称号锻造、升级装备,合成卷轴
  3. 美丽的英文诗句【1】
  4. 学校计算机老师干什么工作,关于计算机教师的个人工作总结
  5. android camera录视频教程,Android camera 篇之视频录制
  6. 一文讲懂SQL分组子句GROUP BY
  7. 简单了解 VBO,FBO
  8. 服务器日志显示英文,在闪亮的服务器上显示R控制台日志
  9. Enscape for SketchUp 创建动画的14个技巧
  10. 抖音种草短视频可以怎样拍摄?以下几招不可错过