AtomicLong的原理

AtomicLong是通过依靠底层的CAS来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的。

LongAdder的原理

LongAdder是在AtomicLong的基础上将单点更新压力分散到各个节点,在低并发的时候通过对八色的直接更新可以很好的保障和AtomicLong的性能基本保持一致,而在高并发的时候通过分散提高了性能。缺点就是LongAdder在统计的时候如果有并发更新,可能导致统计的数据有误差。

LongAdder继承了Striped64类

public class LongAdder extends Striped64 implements Serializable

LongAdder继承了Striped64类,来实现累加功能的,它是实现高并发累加的工具类;

Striped64的设计核心思路就是通过内部的分散计算来避免竞争。

Striped64内部包含一个base和一个Cell[] cells数组,又叫hash表。

没有竞争的情况下,要累加的数通过cas累加到base上;如果有竞争的话,会将要累加的数累加到Cells数组中的某个cell元素里面。所以整个Striped64的值为sum=base+∑[0~n]cells。

Striped64内部三个重要的成员变量:

/**

* 存放Cell的hash表,大小为2的幂。

*/

transient volatile Cell[] cells;

/**

* 基础值,

* 1. 在没有竞争时会更新这个值;

* 2. 在cells初始化的过程中,cells处于不可用的状态,这时候也会尝试将通过cas操作值累加到base。

*/

transient volatile long base;

/**

* 自旋锁,通过CAS操作加锁,用于保护创建或者扩展Cell表。

*/

transient volatile int cellsBusy;

成员变量cells

cells数组是LongAdder高性能实现的必杀器:

AtomicInteger只有一个value,所有线程累加都要通过cas竞争value这一个变量,高并发下线程争用非常严重;

而LongAdder则有两个值用于累加,一个是base,它的作用类似于AtomicInteger里面的value,在没有竞争的情况不会用到cells数组,它为null,这时使用base做累加,有了竞争后cells数组就上场了,第一次初始化长度为2,以后每次扩容都是变为原来的两倍,直到cells数组的长度大于等于当前服务器cpu的数量为止就不在扩容(想下为什么到超过cpu数量的时候就不再扩容);每个线程会通过线程对cells[threadLocalRandomProbe%cells.length]位置的Cell对象中的value做累加,这样相当于将线程绑定到了cells中的某个cell对象上;

成员变量cellsBusy

cellsBusy,它有两个值0 或1,它的作用是当要修改cells数组时加锁,防止多线程同时修改cells数组,0为无锁,1为加锁,加锁的状况有三种

1. cells数组初始化的时候;

2. cells数组扩容的时候;

3. 如果cells数组中某个元素为null,给这个位置创建新的Cell对象的时候;

成员变量base

它有两个作用:

1. 在开始没有竞争的情况下,将累加值累加到base

2. 在cells初始化的过程中,cells不可用,这时会尝试将值累加到base上;

Cell内部类

//为提高性能,使用注解@sun.misc.Contended,用来避免伪共享,

@sun.misc.Contended static final class Cell {

//用来保存要累加的值

volatile long value;

Cell(long x) { value = x; }

//使用UNSAFE类的cas来更新value值

final boolean cas(long cmp, long val) {

returnUNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);

}

private static final sun.misc.Unsafe UNSAFE;

//value在Cell类中存储位置的偏移量;

private static final long valueOffset;

//这个静态方法用于获取偏移量

static {

try {

UNSAFE = sun.misc.Unsafe.getUnsafe();

Class> ak = Cell.class;

valueOffset = UNSAFE.objectFieldOffset

(ak.getDeclaredField("value"));

} catch (Exception e) {

throw new Error(e);

}

}

}

这个类很简单,final类型,内部有一个value值,使用cas来更新它的值;Cell类唯一需要注意的地方就是Cell类的注解@sun.misc.Contended。

atomiclong 初始化_AtomicLong与LongAdder的区别相关推荐

  1. AtomicLong和LongAdder的区别

    转载自 https://blog.csdn.net/yao123long/article/details/63683991 前言   最近在看到不少框架里面使用到了LongAdder这个类,而并非At ...

  2. atomiclong 初始化_比AtomicLong更高效的并发计数类LongAdder

    最近在看https://github.com/alibaba/Sentinel(轻量级的流量控制.熔断降级 Java 库)源码的时候,看到在统计数量的时候使用了LongAdder.这个LongAdde ...

  3. atomiclong 初始化_Java并发编程【1.2时代】

    本文介绍了Java原生的多线程技术(1.2),通过详细介绍wait和notify相关的机制.基础的多线程技术以及基于这些技术的等待超时.线程间的通信技术和线程池高阶技术,最后通过一个基于线程池的简单文 ...

  4. atomiclong 初始化_突击并发编程JUC系列-原子更新AtomicLong

    Java 从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量的方式. ...

  5. 比AtomicLong还高效的LongAdder 源码解析

    2019独角兽企业重金招聘Python工程师标准>>> 接触到AtomicLong的原因是在看guava的LoadingCache相关代码时,关于LoadingCache,其实思路也 ...

  6. 比AtomicLong还高效的LongAdder源码解析

    接触到AtomicLong的原因是在看guava的LoadingCache相关代码时,关于LoadingCache,其实思路也非常简单清晰:用模板模式解决了缓存不命中时获取数据的逻辑,这个思路我早前也 ...

  7. LongAdder和AtomicLong哪个性能更好,为什么?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/limenghua9112/ article/details/107950744 概述 AtomicLong是作者Doug Le ...

  8. 【078期】java.util.* 并发包下 LongAdder 和 AtomicLong 哪个性能更好,为什么?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:00 更新文章,每天进步一点点... 概述 ...

  9. jquery跟js初始化加载的多种方法及区别介绍

    jquery是等待页面加载完数据,以及页面部分元素:js是页面全部加载完成才执行初始化加载,具体示例祥看本文 jquery和js初始化加载页面的区别:  jquery:等待页面加载完数据,以及页面部分 ...

最新文章

  1. Vue中用TypeScript改写JavaScript及装饰器使用
  2. vscode 免费视频教程
  3. 浅谈redis数据库的键值设计
  4. NSString与NSData互转
  5. 一文总结:抽象类(abstract)与接口(interface)的特点和代码展示
  6. boost::geometry::detail::calculate_point_order用法的测试程序
  7. javase基础第三天
  8. 【POJ - 2001 】Shortest Prefixes (字典树,查询重复前缀区间)
  9. c++读取txt文件中的数字_SpringBoot 多种读取配置文件中参数的方式
  10. 保时捷推出Taycan 4S电动汽车 售价10.38万美元起
  11. springcloud项目的启动顺序_spring boot/cloud 启动方式说明
  12. Java DOM方式解析XML(模板)
  13. OLEDB, ODEB, ADO.NET Abbreviation
  14. 【数据分享】学生受欢迎程度评价数据集
  15. BAT中如何使用for循环
  16. 离散傅里叶变换的核心公式
  17. ASEMI代理AD633JRZ原装ADI车规级AD633JRZ
  18. 如何用纯前端去写购物车_索尼商城购物车
  19. Oracle COALESCE函数
  20. GarageGames公布新游戏开发平台

热门文章

  1. 美团外卖:对删差评刷单零容忍 将联动警方打击黑产
  2. vivo折叠屏,唱响唱不红
  3. 游戏服务器异常修复,游戏服务器异常修复
  4. 黑马程序员----小游戏代码之“骑士飞行棋”
  5. mybatis连表查询
  6. 基于SpringBoot的小米商城的设计与实现
  7. 【区块链】Tendermint——概述、PoS共识算法与架构
  8. 中富金石股票投资教学怎么样?分享我在这里的学炒股之路
  9. Android 项目必备(二十一)-->APP 多语言切换(国际化)
  10. 主题模型对比:LSA、pLSA、LDA