Home  >  Article  >  Java  >  LongAdder source code analysis of Java concurrent programming

LongAdder source code analysis of Java concurrent programming

PHPz
PHPzforward
2023-05-28 08:22:171285browse

Preface

Let’s analyze its basic implementation process based on the source code.

This class is usually preferable to AtomicLong when multiple threads update a common sum that is used for purposes such as collecting statistics, not for fine-grained synchronization control. Under low update contention, the two classes have similar characteristics. But under high contention, expected throughput of this class is significantly higher, at the expense of higher space consumption.

The above paragraph is from the LongAdder source code comment Part of it, translated roughly means

This class is generally preferred over AtomicLong when multiple threads update a common sum that is used to collect statistics but not for the purpose of fine-grained synchronization control. Under low update contention, these two classes have similar characteristics. But under high contention conditions, the expected throughput of this class is significantly higher, but at the cost of higher space consumption.

That is to sayLongAdder is more efficient when the concurrency is high, but the cost is to trade space for time.

Let’s explain the principle of LongAdder in a simple way: when there is little concurrency, it is enough to perform the accumulation operation on only one variable base, so and AtomicLong is similar; but when the concurrency increases, if you still operate on the variable base, many threads will be blocked, so create an array cells, in Each element of the array can be accumulated. When calculating the final result, just calculate the sum of each element of the base and cells arrays. The specific bit in the array where the thread operates can be determined by calculating hash to determine the index position.

Source code introduction

LongAdderAttributes inherited from the parent class Striped64, here Cell is used to The internal class of the accumulation operation has an internal value attribute to store the accumulated value.

// CPU核心数
static final int NCPU = Runtime.getRuntime().availableProcessors();
// 并发高时进行累加的Cell数组
transient volatile Cell[] cells;
// 多个线程没有竞争时在base上进行累加
transient volatile long base;
// Cell数组是否正在创建或扩容
transient volatile int cellsBusy;

Accumulation operation methodincrement()The actual call is add(1L), so let’s look directly at the addmethod

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);
    }
}

Let’s first look at the first if statement. Under initial conditions, cells is null, so the casBase operation will be performed. That is to say, accumulation is performed on the base variable. If the operation is successful, it means there is no competition at present, so it is over.

When the concurrency increases, the casBase method may fail, so at this time, the second if statement judgment is entered.

  • When it comes in for the first time, the Cell arrayas is null, so longAccumulate# will be executed. ##, initialize the Cell array as and accumulate 1 at index 1;

  • After executing this

    if statement as, it will not be null, and the array length is also greater than 0

  • a = as[getProbe() & m]) == null, the simple understanding of this sentence is to randomly find an index in the array as Position, determine whether the value of the position is null, if it is null, execute longAccumulate, if not null, continue to judge

  • !(uncontended = a.cas(v = a.value, v x))This sentence means that the accumulation operation is performed at the found index position , if successful, end the operation, if failed, execute longAccumulate

The above is the detailed content of LongAdder source code analysis of Java concurrent programming. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete