gofor's blog

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

LongAdder浅析

发表于 2020-01-10 分类于 技术 阅读次数: Valine:

LongAdder浅析

LongAdder类是在java8中新加入的并发环境下高性能的计数器类成员。该类主要通过CAS的原理和分散竞争的思想,实现并发环境下的计数效率。
该类继承了内部抽象类Striped64(基础计数器和分散竞争),并间接实现Number接口(负责数值类型的转换)。
其核心思想还是Striped64,该类的解析见Striped64学习。

LongAdder类的内部实现较为简单,主要有以下几个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 增加x
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
// 将cells赋值给临时变量as
// cells不为空或者CAS更新base值失败时
if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true;
// 当前数组为空或者有空闲位置时,或
// 当数组不为空,且当前线程所在数组中位置不为空时,判断为线程自己,
// 尝试CAS更新当前位置的计数值,更新失败时
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
// 使用Striped64中方法,自旋直至更新成功
longAccumulate(x, null, uncontended);
}
}

// 自增
public void increment() {
add(1L);
}

// 自减
public void decrement() {
add(-1L);
}

// 获取计数结果
public long sum() {
// 获取到cell数组
Cell[] as = cells; Cell a;
// 拿到base计数值
long sum = base;
// cell数组不为空
if (as != null) {
// 循环获取数组中不为空的cell的值value,进行累加
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
sum += a.value;
}
}
// 返回最终结果
return sum;
}

// 重置为0
public void reset() {
Cell[] as = cells; Cell a;
// base重置为0
base = 0L;
// cells数组不为空
if (as != null) {
for (int i = 0; i < as.length; ++i) {
// cell对象不为空,cell的值重置为0
if ((a = as[i]) != null)
a.value = 0L;
}
}
}

// 获取计数结果并重置
public long sumThenReset() {
Cell[] as = cells; Cell a;
long sum = base;
base = 0L;
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null) {
sum += a.value;
a.value = 0L;
}
}
}
return sum;
}

DoubleAdder类和LongAdder类很类似,区别在于,DoubleAdder类中做了类型转换(double <=> long),并移除了自增和自减方法。

  • 本文作者: gofor
  • 本文链接: https://acehjm.github.io/2020/01/10/LongAdder浅析/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
# java # concurrent
Striped64 学习
gofor

gofor

Programming technology
14 日志
4 分类
14 标签
RSS
GitHub StackOverflow
Creative Commons
© 2016 – 2020 gofor
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0
0%