多线程并行运算的问题
来源:6-9 功能升级

慕沐3053333
2020-01-05
public class LongAccumulatorDemo {
public static void main(String[] args) {
LongAccumulator accumulator = new LongAccumulator((x, y) -> 2 + x * y, 1);
ExecutorService executor = Executors.newFixedThreadPool(8);
IntStream.range(1, 10).forEach(i -> executor.submit(() -> accumulator.accumulate(i)));
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println(accumulator.getThenReset());
}
}
Accumulator和Adder的实现原理是一样的吗?
每个线程在自己的工作内存进行乘法运算,每个线程运算完毕后,再把每个线程的工作内存中的值再相乘?
1回答
-
悟空
2020-01-05
是的,从下面代码知道LongAccumulator相比于LongAdde的不同在于casBase的时候,后者传递的是b+x,而前者则是调用了r=function.applyAsLong(b=base.x)来计算。
LongAdder类的add源码如下:
public void add(long x) {
Cell[] as; long b, v; int m; Cell a; if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true; if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
longAccumulate(x, null, uncontended);
}
}LongAccumulator的accumulate方法的源码如下:
public void accumulate(long x) {
Cell[] as; long b, v, r; int m; Cell a; if ((as = cells) != null ||
(r = function.applyAsLong(b = base, x)) != b && !casBase(b, r)) {
boolean uncontended = true; if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended =
(r = function.applyAsLong(v = a.value, x)) == v ||
a.cas(v, r)))
longAccumulate(x, function, uncontended);
}
}另外LongAccumulator调用longAccumulate时候传递的是function,而LongAdder是null,从下面代码可以知道当fn为null,时候就是使用v+x 加法运算,这时候就等价于LongAdder,fn不为null的时候则使用传递的fn函数计算,如果fn为加法则等价于LongAdder。
参考:https://www.cnblogs.com/huangjuncong/p/9152510.html
https://blog.csdn.net/m0_37055174/article/details/99956962
00
相似问题