c语言编程笔录

首页 >   > 笔记大全

笔记大全

Java并发编程之LongAdder执行情况是什么

更新时间:2023-08-05

LongAdder介绍

LongAdder是Java并发包(java.util.concurrent)中的一个类,它是对AtomicLong的扩展。在Java中,AtomicLong是一种线程安全的long型变量,它提供了一些原子操作方法,如incrementAndGet、decrementAndGet等,用来保证多线程情况下的线程安全。然而,当多个线程同时更新同一个AtomicLong变量时,性能会受到很大的影响。这是因为当多个线程竞争同一个AtomicLong时,会发生大量的自旋操作,以保证最终结果的正确性。为了解决这个问题,Java并发包引入了LongAdder。

LongAdder是Java 8中引入的一种用来高效处理高并发情况下计数器的方式。它通过内部维护的一组变量来分散竞争,从而提高了并发性能。在低并发情况下,LongAdder的性能与AtomicLong相当,但在高并发情况下,LongAdder的性能要优于AtomicLong。

LongAdder内部维护了一个Cell数组,每个Cell都是一个独立的原子变量,多个线程在更新计数时会均匀地分配到不同的Cell上,从而减少了竞争,提高了并发性能。当多个线程同时更新计数时,它们会在不同的Cell上进行操作,而不会发生竞争。最终,通过对Cell之间的值进行累加,就可以得到最终的计数结果。

LongAdder执行过程

在并发环境下,多个线程可以同时对LongAdder的计数进行增加或减少操作。每当线程调用LongAdder的increment方法时,LongAdder会通过hash算法,将线程映射到一个Cell上,然后对这个Cell进行更新。这个过程可以用以下伪代码来表示:

public void increment() {
    Cell cell = getCell(Thread.currentThread().hashcode());
    if (cell != null) { // 如果当前线程映射到了一个Cell上
        cell.value++;
    } else { // 如果当前线程没有映射到任何一个Cell上
        long oldValue, newValue;
        do {
            oldValue = base.value;
            newValue = oldValue + 1; // 在base上进行累加
        } while (!base.compareAndSet(oldValue, newValue));
    }
}

当线程数量增加时,为了进一步减少竞争,LongAdder还会动态扩容Cell数组,以增加线程分配到不同Cell的概率。在扩容时,LongAdder会将base累加的值平均分配到新的Cell数组中,这种方式既保证了计数的准确性,又保证了线程的局部性。具体的扩容过程如下:

private void addCells() {
    long[] as = cells; // 当前Cell数组
    int size = (as == null) ? 0 : as.length;
    int n = size;
    if (size < NCPU) { // 当前Cell数组长度小于处理器数量
        Cell[] rs = new Cell[NCPU];// 新的Cell数组
        if (size > 0) {
            System.arraycopy(as, 0, rs, 0, size);
        }
        for (int j = size; j < NCPU; ++j) {
            rs[j] = new Cell();
        }
        cells = rs; // 替换当前的Cell数组
    }
}

总之,LongAdder通过维护多个Cell,将线程对计数的更新操作分散到不同的Cell上,从而有效地减少了多线程竞争的程度,提高了并发性能。它在高并发情况下的性能要优于AtomicLong,而在低并发情况下的性能与AtomicLong相当。因此,在需要高性能的并发计数场景下,推荐使用LongAdder来替代AtomicLong。

总结

LongAdder是Java并发包中的一个类,用于高并发计数。它通过维护多个Cell,将线程对计数的更新操作分散到不同的Cell上,从而提高了并发性能。

LongAdder在并发更新计数时,会将不同线程分散到不同的Cell上进行操作,并最终通过对所有Cell的值进行累加来得到最终的计数结果。在低并发情况下,LongAdder的性能与AtomicLong相当;而在高并发情况下,LongAdder的性能要优于AtomicLong。

LongAdder在多线程并发更新计数时,会对Cell进行扩容,以进一步降低线程之间的竞争。在扩容时,LongAdder将base累加的值平均分配到新的Cell数组中,保证了计数的准确性。

总的来说,LongAdder是一种高效的并发计数方式,适用于需要高性能的并发计数场景。通过使用LongAdder,可以减少线程之间的竞争,提高并发性能。