Java 並行プログラミングの LongAdder ソース コード分析

PHPz
リリース: 2023-05-28 08:22:17
転載
1254 人が閲覧しました

はじめに

ソースコードに基づいて、その基本的な実装プロセスを分析してみましょう。

複数のスレッドが、きめ細かい同期制御ではなく、統計収集などの目的で使用される共通の合計を更新する場合、通常、このクラスは AtomicLong よりも推奨されます。ただし、競合が多い場合、スペース消費量が増える代わりに、このクラスの予想スループットは大幅に高くなります。

上記の段落は、LongAdderソース コード コメントからのものです。その一部を大まかに翻訳すると、

このクラスは、複数のスレッドが統計の収集には使用されるが、きめ細かい同期制御を目的としていない共通の合計を更新する場合、一般にAtomicLongよりも優先されます。 。更新競合が少ない場合、これら 2 つのクラスは同様の特性を持ちます。ただし、競合が多い状況では、このクラスの予想スループットは大幅に高くなりますが、スペース消費量が増加します。

つまり、LongAdderは同時実行性が高い場合に効率的ですが、その代償としてスペースと時間のトレードオフが発生します。

LongAdderの原理を簡単に説明しましょう。同時実行性がほとんどない場合は、1 つの変数baseに対して累算演算を実行するだけで十分です。AtomicLongも同様ですが、同時実行性が増加した場合、変数baseを引き続き操作すると、多くのスレッドがブロックされるため、配列cellsを作成します。 in 配列の各要素は累積できます。最終結果を計算するときは、basecells配列の各要素の合計を計算するだけです。スレッドが動作する配列内の特定のビットは、hashを計算してインデックス位置を決定することで決定できます。

ソース コードの紹介

LongAdder親クラスStriped64から継承された属性。ここではCellが内部クラスに使用されます。累積操作の には、累積値を格納するための内部value属性があります。

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

累積演算メソッドincrement()実際の呼び出しはadd(1L)なので、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); } }
ログイン後にコピー
まず、最初の

ifステートメントを見てみましょう。初期条件では、cellsnullであるため、casBase操作はつまり、base変数に対して累積が実行され、操作が成功した場合は、現在競合がいないことを意味するため、終了します。

同時実行数が多くなると、

casBaseメソッドが失敗する可能性があるため、この時点で2回目のif文の判定が入ります。

  • 初めて入ったとき、

    Cellarrayasnullであるため、##、Cell配列asを初期化し、インデックス11を累積します。

  • この
  • if

    ステートメントasを実行すると、nullにはならず、配列の長さも0 より大きくなります。

  • a = as[getProbe() & m]) == null

    、この文を簡単に理解すると、配列as位置、位置の値がnullであるかどうかを判断し、nullである場合はlongAccumulateを実行し、## でない場合はlongAccumulateを実行します。 #null、判断を続けます

  • !(uncontended = a.cas(v = a.value, v x))この文は、累積見つかったインデックス位置で操作が実行され、成功した場合は操作が終了し、失敗した場合はlongAccumulate

  • が実行されます。

以上がJava 並行プログラミングの LongAdder ソース コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!