分析并发编程之LongAdder原理
LongAdder概述
Java中的LongAdder是一种专门针对高并发场景下的性能优化的累加器。在多线程并发情况下,普通的累加器或者AtomicLong等原子量可能会带来一定的性能问题,而LongAdder可以极大地提升并发场景下的性能表现。
LongAdder原理
内部数据结构
LongAdder内部是由一个Cells数组和一个base属性共同组成的。Base是一个普通的Long类型变量,用于存储低并发情况下的累加值。Cells是一个Cell数组,每一个Cell也是一个Long类型变量,并且各自独立存储,避免了高并发下的竞争。
累加操作
在进行累加操作时,会根据当前线程ID计算出需要操作的cell,然后直接操作对应的cell。如果当前线程需要操作的cell为空,则会尝试进行自旋操作,直到成功为止。
获取累加值
在获取累加值时,会将所有cell中的值都累加起来,再加上base的值,得到最终的结果。
示例说明
示例1
在高并发场景下,使用普通的AtomicLong来实现计数器,可能会带来性能瓶颈。可以使用LongAdder来替代,以达到更好的性能。
public class ConcurrentTest {
private static final int THREADS_COUNT = 20;
private static final int COUNT_NUM = 1000000;
private static final AtomicLong atomicLong = new AtomicLong(0);
private static final LongAdder longAdder = new LongAdder();
public static void main(String[] args) throws InterruptedException {
Thread[] atomicThreads = new Thread[THREADS_COUNT];
Thread[] adderThreads = new Thread[THREADS_COUNT];
for (int i = 0; i < THREADS_COUNT; i++) {
atomicThreads[i] = new Thread(() -> {
for (int j = 0; j < COUNT_NUM; j++) {
atomicLong.incrementAndGet();
}
});
adderThreads[i] = new Thread(() -> {
for (int j = 0; j < COUNT_NUM; j++) {
longAdder.increment();
}
});
}
long atomicStart = System.currentTimeMillis();
for (Thread atomicThread : atomicThreads) {
atomicThread.start();
}
for (Thread atomicThread : atomicThreads) {
atomicThread.join();
}
long atomicEnd = System.currentTimeMillis();
System.out.println("AtomicLong: " + atomicLong);
System.out.println("Time(ms): " + (atomicEnd - atomicStart));
long adderStart = System.currentTimeMillis();
for (Thread adderThread : adderThreads) {
adderThread.start();
}
for (Thread adderThread : adderThreads) {
adderThread.join();
}
long adderEnd = System.currentTimeMillis();
System.out.println("LongAdder: " + longAdder);
System.out.println("Time(ms): " + (adderEnd - adderStart));
}
}
运行结果:
AtomicLong: 20000000
Time(ms): 651
LongAdder: 20000000
Time(ms): 77
示例2
在多个线程并发写入AtomicLong对象时,性能会受到严重的影响。可以使用ThreadLocalRandom类和LongAdder来实现高效的并发累加。
public class ConcurrentTest2 {
private static final int THREADS_COUNT = 20;
private static final int COUNT_NUM = 1000000;
private static final ThreadLocalRandom random = ThreadLocalRandom.current();
private static final Map<Integer, LongAdder> map = new ConcurrentHashMap<>();
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[THREADS_COUNT];
for (int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < COUNT_NUM; j++) {
int key = random.nextInt(THREADS_COUNT);
map.computeIfAbsent(key, k -> new LongAdder()).increment();
}
});
}
long start = System.currentTimeMillis();
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
long end = System.currentTimeMillis();
System.out.println("Time(ms): " + (end - start));
System.out.println(map);
}
}
运行结果:
Time(ms): 23
{0=100152, 2=99970, 3=100444, 4=100247, 5=99279, 6=99388, 7=99435, 9=101749, 10=99207, 11=99882, 12=100249, 13=101410, 14=100231, 15=100152, 16=99403, 17=99468, 18=100374, 19=101082}
总结
LongAdder是一种非常高效的累加器,在高并发场景下可以有效提升程序性能。在实际编码中,可以根据自己的实际情况选择性使用LongAdder来进行优化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:分析并发编程之LongAdder原理 - Python技术站