AtomicInteger アトミック クラスの役割の概要 (コード例)
この記事では、AtomicInteger アトミック クラスの役割 (コード例) を紹介します。これには特定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。 。 ヘルプ。
AtomicInteger アトミック クラスの役割
マルチスレッド操作、Synchronized ではパフォーマンスのオーバーヘッドが大きすぎるため、カウントはアトミック操作ではありません。 count は読み取り、変更、書き込みの 3 つのステップを経る必要があるためです。
count はアトミックな操作ではありません。 count は読み取り、変更、書き込みの 3 つのステップを経る必要があるためです。
これを行うことができます:
public synchronized void increase() { count++; }
同期ロックは排他的です。つまり、他のスレッドが実行中の場合、現在のスレッドは待機することしかできません。
CAS を使用した操作
CAS には 3 つのオペランドがあります:
メモリ値 V 古い期待値 変更される新しい値 B 複数のスレッドが試行するとき CAS が使用される場合同じ変数を同時に更新する場合、スレッドのうちの 1 つだけが変数の値を更新できます (A とメモリ値 V が同じ場合、メモリ値 V を B に変更します)。他のスレッドは失敗します。失敗したスレッドはハングされず、代わりに、競争に失敗したことが通知され、再試行することができます (または何もしないこともできます)。
CAS には 2 つの状況があることがわかります。
メモリ値 V が期待値 A と等しい場合、メモリ値は B に変更され、操作は成功します。 !
メモリ値 V が期待値 A と等しくない場合、一般に 2 つの状況が考えられます:
再試行 (スピン) して何もしない
CAS を理解する 核心は次のとおりです。 :
CAS はアトミックです。比較と交換を見ると 2 つの操作があるように思われるかもしれませんが、結局のところアトミックです。
アトミック変数クラスは java.util.concurrent.atomic パッケージの下にあります。全体として、非常に多くの
基本型があります:
AtomicBoolean: Boolean AtomicInteger: Integer AtomicLong : Long 整数型
Array:
AtomicIntegerArray: 配列内の整数型 AtomicLongArray: 配列内の Long 整数型 AtomicReferenceArray: 配列内の参照型
参照型:
AtomicReference: 参照型 AtomicStampedReference: バージョン番号付きの参照型 AtomicMarkableReference: マーク ビット付きの参照型
オブジェクトのプロパティ
AtomicIntegerFieldUpdater: オブジェクトのプロパティは整数型 AtomicLongFieldUpdater: オブジェクトの属性はLong 整数 AtomicReferenceFieldUpdater: オブジェクトの属性は参照型です。
JDK8 の新しい DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder
は、AtomicLong およびその他のクラスの改良です。たとえば、同時実行性の高い環境では、LongAccumulator と LongAdder は AtomicLong よりも効率的です。 Atomic パッケージ内のクラスは、基本的に Unsafe を使用して実装されたラッパー クラスです。
Unsafe には、気に入ったメソッド (CAS) がいくつかあります。
// 第一和第二个参数代表对象的实例以及地址,第三个参数代表期望值,第四个参数代表更新值 public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5); public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
アトミック変数クラスの使用
class Count{ // 共享变量(使用AtomicInteger来替代Synchronized锁) private AtomicInteger count = new AtomicInteger(0); public Integer getCount() { return count.get(); } public void increase() { count.incrementAndGet(); } }
ABAアトミッククラスの問題
以下の操作は正常に実行できますが、この場合どのような問題が発生しますか? ?スレッド C はスレッド A とスレッド B によって変更されたカウント値を知ることができないため、危険です。
今、変数 count=10 があります。現在、A、B、C という 3 つのスレッドがあります。スレッド A とスレッド C は同時に count 変数を読み取るため、メモリ値と期待値はスレッド A とスレッド C 両方とも 10 です。この時点で、スレッド A は CAS を使用してカウント値を 100 に変更します。変更後、この時点でスレッド B が入ってきて、カウントの値を 100 として読み取ります (メモリ値とスレッド C が実行権を取得し、メモリ値が 10 であり、期待値も 10 であることがわかります。カウント値を 11 に変更します。
ABA 問題を解決する
ABA 問題を解決するには、JDK が提供する AtomicStampedReference クラスと AtomicMarkableReference クラスを使用できます。
簡単に言えば、このオブジェクトのバージョンを提供し、このバージョンが変更されると、自動的に更新されます。
原理はおそらく次のとおりです。Pair オブジェクトが維持され、Pair オブジェクトにはオブジェクト参照とスタンプ値が格納されます。 CAS が 2 つのペア オブジェクトを比較するたびに、
LongAdder は AtomicLong よりも優れたパフォーマンスを発揮します。
AtomicLong を使用すると、高い同時実行性のもとで、多数のスレッドが同じアトミック変数を同時に更新しようと競合します。ただし、同時実行により 1 つのスレッドの CAS のみが成功するため、他のスレッドは引き続きスピンを試行し、CAS 操作を試行し、大量の CPU リソースを浪費します。
LongAdder を要約すると、内部のコア データ値が配列 (Cell) に分割され、各スレッドがそれにアクセスすると、ハッシュやその他のアルゴリズムを通じてカウントするための数値の 1 つにマッピングされ、最終的なカウント結果は、この配列の合計と累積です。
簡単に言えば、1 つの値が複数の値に分散されるため、同時実行時の圧力が分散され、パフォーマンスが向上します。
以上がAtomicInteger アトミック クラスの役割の概要 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

Java は、初心者と経験豊富な開発者の両方が学習できる人気のあるプログラミング言語です。このチュートリアルは基本的な概念から始まり、高度なトピックに進みます。 Java Development Kit をインストールしたら、簡単な「Hello, World!」プログラムを作成してプログラミングを練習できます。コードを理解したら、コマンド プロンプトを使用してプログラムをコンパイルして実行すると、コンソールに「Hello, World!」と出力されます。 Java の学習はプログラミングの旅の始まりであり、習熟が深まるにつれて、より複雑なアプリケーションを作成できるようになります。
