[A]並行プログラミングのテキストは、Javaメモリモデルの深い理解を読み取るために表示されます(インタビュー必要)

並行プログラミングから、基本的なトップその場合は並行プログラミングは、コンテンツのこの作品、シニアシニアエンジニアに必要な知識、25Kは知りません。しかし、複雑な並行プログラミングの内容は、どのようにシステムを学びますか?トピックのすべての知識は、並行プログラミングのシステムを説明するなど、これらに限定されません。

スレッド間通信メカニズム、深さJMMメモリモデルの原則、原則同期深さ、深揮発性の原則、DCL、詳細なAQS、CAS、リエントラントロック、ロック原則を書き、複雑なツール詳細深い理解にThreadLocal、フォーク、参加、原子クラス詳細、Javaの並行処理コレクションコメント(ConcurrentListMapなどのConcurrentHashMap、ConcurrentLinedQueue、)、キューの深さ探査、綿密なスレッドプールの原理と設計思想を遮断します。この記事では、Javaのメモリモデルを徹底的に理解。

ゼロ、フルマインドマップ

赤い矢印の上に示したようにメインラインは、あなたが全体的には、そういえば何を見てみることができます。Javaのメモリモデルは、コンテンツが続く前に寝具、です。

まず、Javaのメモリモデルを(説明に焦点を当てることではない)リード

第二に、どのようなことには、Javaのメモリモデルを使用するのでしょうか?

共有変数(インスタンスフィールド、静的フィールド、配列要素)が使用されます。ローカル変数は、メソッドのパラメータを定義するというように、スレッド間で共有されることはありませんので、彼らはメモリの問題の可視性を持っていない、メモリモデルに影響されません

三、Javaのメモリモデル抽象概略図

Javaのメモリモデルは、JMM(Javaのメモリモデル)、メモリアクセスの異なるハードウェアとオペレーティングシステムの違いをマスクするために使用するJava仮想マシンによって定義された抽象仕様であると呼ばれるので、さまざまなプラットフォームでJavaプログラムは同じメモリを達成するためにアクセス効果。

3.1メインメモリ(メインメモリ)

メイン単にコンピュータメモリとして理解することができるメモリが、まったく同じではありません。メインメモリは、その記憶するメインメモリ(例えば、静的変数、インスタンスまたはヒープメモリのような)共有変数のすべてのスレッドで共有される「神」を

3.2ローカルメモリ(作業記憶)

ローカルメモリは、単にコンピュータのCPUのキャッシュとして理解することができますが、まったく同じではありません。各スレッドは共有変数、その格納ワーキングメモリのため、独自のワーキングメモリを持っている「コピー」。なぜローカルメモリのコンセプトを持っていますか?直接操作遅いメインメモリので、

一連の命令読み出し及びメモリ書き込み操作することにより、スレッドメインメモリから静的変数s = 0、読み出し、ワーキングメモリ(JVM総メモリモデルは8つのメモリ操作命令を定義し、後に詳細に入ります)、その後、S = 3でありますそれらのメインメモリに同期して更新する結果。何の問題もなくシングルスレッド、プロセスの観点から。

第四に、命令の並べ替え

前にこの概念を理解して並べ替えする前に、我々は最初のシーンを変換し、Javaのメモリモデルから出てきた、CPUのハードウェアは、このディメンションを来ました。

4.1基本的な概念:

パフォーマンスを向上させるためにプログラムの実装では、コンパイラおよびプロセッサは、多くの場合、(簡単な理解は、私たちが順番に、オリジナルのコード命令の実行順序は→B→Cでなければなりませんが、今CPUはマルチコアCPUでの書き込みで並べ替えを行うための指示を持っています位置を示し、並列度を向上させるために、パフォーマンスを向上させるために、コマンドシーケンス他の場合がある等B→A→C)となります。

もちろん、それは次の2つの条件(フォローするルール)を満たす必要があり、行くだけでCPUの並べ替えではありません。

  1. あなたは、シングルスレッド環境で実行中のプログラムの結果を変更することはできません。
  2. あります許可されていないデータの依存関係を再ソートします

4.2は、3つのカテゴリーに分類並べ替え:

  1. コンパイラの最適化の並べ替え。前提の意味を変えることなく、シングルスレッドのプログラムでは、コンパイラは、次の文の実行順序を並べ替えることができます。
  2. ILPの並べ替え。現代のプロセッサの命令レベル並列性の手法は、実行される命令の複数の重複します。何のデータ依存性が存在しない場合、プロセッサは、文の配列に対応する機械語命令の実行を変更することがあります。
  3. システムのメモリを並べ替えます。プロセッサは、キャッシュおよびロードとストアオペレーションが順序を外れて表示されることが実行されることができる読み取り/書き込みバッファを使用するので。

実際に実行される命令の最終配列にJavaソースコードは、それぞれ以下の三つ並べ替えを受けます。

だから、並べ替えルールの種類を追跡するには?

五、AS-IF-シリアル

5.1as-IF-シリアルセマンティクスを意味します。

どんなに結果を並べ替える方法(シングルスレッド)プログラムは変更することはできません。コンパイラ、ランタイムおよびプロセッサは、AS-IF-シリアルセマンティクスを遵守しなければなりません。OK、これはCPUと同等であるルールを設定しています。並べ替えないでください。並べ替えするために、私のよう-IF-シリアルのための前提条件を満たしています。

5.2

シングルスレッドのプログラムのセマンティクスであれば、シリアルなどアップ保護するシングルスレッドプログラムを書くプログラマのための錯覚を作成するために一緒にAS-IF-シリアルセマンティクスコンパイラ、ランタイムおよびプロセッサを遵守する:プログラムは、シングルスレッドのプログラムに基づいていますオーダー実行AS-IF-シリアルセマンティクスプログラマが彼らの問題に干渉並べ替え単一のスレッドを心配する必要がないように、メモリの可視性の問題を心配する必要はありません。

注意:場合はシリアルとしてのみのシングルスレッド環境で、無効なマルチスレッド環境を保証します。並行プログラミングを行う方法マルチスレッド、それ?

6下のマルチスレッドおよびソリューションによって引き起こされる問題

これらは、並べ替え、マルチスレッドプログラムメモリの可視性の問題につながる可能性がある上に、JMMは、どのように解決するには?

  • がっかりソートをコンパイルするために、JMMの注目仕分けルールをコンパイルするコンパイラの特定のタイプは、ソート(すべてのコンパイラは禁止並べ替えを落胆していない)の非常に考えて禁止しています。
  • プロセッサを並べ替えるために、命令のシーケンスを生成する際のルールを並べ替えJMMプロセッサは、Javaコンパイラを必要とし、プロセッサの特定のタイプを無効にするために、すべてのプロセッサがメモリバリア命令によって並べ替え並べ替え(ただし、メモリバリア命令の特定のタイプを挿入)を無効にします。

JMMは、メモリの特定の種類を禁止プロセッサコンパイラを注文すると並べ替えることにより、落胆、それは異なるコンパイラと異なるプロセッサプラットフォーム上で保証し、言語レベルのメモリモデルに属しているプログラマのための一貫した可視性の保証を提供

七、メモリバリアは何ですか?

7.1メモリ・バリア(メモリバリア)は、CPUの命令」です。

また、メモリバリア命令メモリバリアやフェンス、制約の一種によって発行されたバリア命令の前と後に実行CPUやコンパイラメモリ操作の原因となるバリア命令、として知られています。

7.2実用的なアプリケーションのシナリオ:

揮発性メモリバリアは、実装に基づいています。**追加揮発性のキーワードは追加され、アセンブリコードが見つかった揮発性のキーワードを生成したがvolatileキーワードを追加していないときに、ロックはより多くのプレフィックス命令になります観察しました。**このコマンドは、メモリバリアに相当します。特定のパフォーマンス:

  • 揮発性変数を書き込む場合、JMMは直ちにメインメモリにフラッシュスレッドローカルメモリの共有変数値に対応します。
  • 揮発性変数を読み取るときに、スレッドが無効になっているローカルメモリに対応JMMれ、共有変数は、メインメモリから直接読み取られます

このように確保し、更新すべき共有変数のスレッド揮発性の修正ならば、他のスレッドは、直ちにスレッ​​ドの可視性と呼ばれるアップデートを、見ることができます。

(揮発性に関する注意事項は、シングル章の後半で説明しますが、ここで息子-中)

八、たまたま、前の原則

スタートJDK5からは、コンセプトに基づいた新しいメモリモデルを使用して、JavaのJSR-133には、事前発生との間のメモリの可視性の動作を説明します。換言すれば、JMMに、操作を実行した結果は、別の可視を必要とする場合、それが起こる前に、関係は、動作を動作する2つの間に存在しなければなりません。それが起こる前に、JMMの原理は、メイン基盤のスレッドの安全性は、マルチスレッド環境の視認性を確保するかどうかの競争が、データがあるかどうかを決定することは非常に重要な原則です。両方とも同じスレッド内の2つの操作は、2つの異なるスレッドであってもよいです。

一部抜粋が起こる前に、ルールは以下の通りである:1、プログラムシーケンスルール:各動作のためのスレッドを発生し、前のスレッドに任意の後続の動作を制御します。図2は、モニタロック規則:ロックのロック解除動作は、事前発生ロックの後続のロック動作。3、揮発性ドメインルール:任意のスレッドを追跡するために、この揮発性のフィールドを読む前に起こる-volatileフィールドに書き込みます。図4に示すように、配信ルール:AはBの前に、発生し、そしてBが起こる前-C、次いでAが発生し、前C.場合 注意:旧事前発生関係の前に実行している、それはオペレータが2間の術後で動作するように持っていることを意味するものではありません!かつての結果は、以下の操作のための1つの操作のみがために、操作の前に見え、そして前回の操作で必要です。

だから、関係を見て非常に多くのルールが事前発生JMMと言いました

九、もしシリアル-としておよび事前発生の概要

  • セマンティクスは、シングルスレッドのプログラム内で保証されたままの場合、シリアルの結果は変更されません
  • 結果は、事前発生マルチスレッド・プログラムの適切な同期を確保するための関係は変更されません。
  • 実際には、できるだけプログラムの実施を改善する前提のプログラムの実行結果を変更することなく、すべての並列度。

テン、どのようにこれらの人々を理解することは、あまりにも長い間引っ張りますか?結論:

  • 操作のパフォーマンスを最適化するために、マルチコアCPUなどの並べ替えが、可視性の問題を引き起こす可能性があります。JMMは、いくつかのルールを開発する必要があるので、これらの問題を解決するには、それが自由に並べ替えることができます。
  • -IF-シリアルのみの保証はあまりそれをスレッド、シングルスレッド環境の順序を変更して自由ではないのですか?
  • 1 JMM(JSR-133メモリモデル)仕様であるので、事前発生原理、を有します。
  • メモリバリアは、CPUの命令です。
  • だから、たまたま-前JMMが作るの究極の目標は、メモリバリアは、事前発生実現の具体的な手段です。

終わり

卵小さな福祉

フリーのJavaの研究ノート、インタビュー、ドキュメント、ビデオを見ます

次のようにセクションは、次のとおりです。

おすすめ

転載: juejin.im/post/5d036627e51d457761476133