ホームページ  >  記事  >  Java  >  Java メモリ モデルは何をするのでしょうか?

Java メモリ モデルは何をするのでしょうか?

王林
王林転載
2023-05-09 09:01:211143ブラウズ

JMM とは

  • JMM の正式名は Java メモリ モデル、中国語訳は Java メモリ モデル、メモリ モデル仕様に準拠し、さまざまなメモリ モデルのアクセスの違いをシールドするメモリ モデルです。ハードウェアとオペレーティング システム。さまざまなプラットフォームでメモリにアクセスするときに、Java プログラムが一貫したメカニズムと仕様を保証できるようにします。

  • #Java メモリ モデルでは、すべての変数がメイン メモリに格納され、各スレッドが独自の作業メモリを持つことが規定されています。

  • スレッドのワーキング メモリには、スレッドで使用される変数のメイン メモリ コピーが保存されます。スレッドによる変数に対するすべての操作は、ワーキング メモリ内で実行する必要があります。メインメモリを直接読み書きすることはできません。

  • 異なるスレッドは、互いの作業メモリ内の変数に直接アクセスできません。スレッド間で変数を転送するには、スレッド自身の作業メモリとメイン メモリ間のデータ同期が必要です。

  • JMM は、作業メモリとメイン メモリ間のデータ同期プロセスに作用します。彼は、データ同期がいつどのように行われるかを指定します。

Java メモリ モデルは何をするのでしょうか?

#メインメモリとワーキングメモリ

  • メインメモリとワーキングメモリは、コンピュータに簡単にたとえることができます。メモリモデルにおけるメインメモリとキャッシュの概念。メインメモリとワーキングメモリは、JVM メモリ構造における Java ヒープ、スタック、メソッド領域などと同じレベルのメモリ分割ではなく、直接比較できないことに注意することが特に重要です。

  • #変数、メインメモリ、ワーキングメモリの定義からやむを得ず対応させていただくと、メインメモリは主にJavaヒープ内のオブジェクトインスタンスのデータ部分に相当します。作業メモリは、仮想マシン スタックの一部に対応します。
  • volatile キーワードの用途

    データ メモリの可視性の確保
  • 可視性

    初期変数は最初にメイン メモリに保存されます;

    スレッド操作変数はメイン メモリからスレッド ローカル メモリにコピーする必要があります;

    スレッド ローカル作業メモリキャッシュ、ストア バッファ (後述)、レジスタなどを含む抽象的な概念です。

  • スレッド A とスレッド B が通信したい場合は、次の 2 つの手順を実行する必要があります。

    スレッド A は、ローカル メモリ A を次の場所に保存します。更新された共有変数はメイン メモリにフラッシュされます。

    スレッド B はメイン メモリに移動し、スレッド A が以前に更新した共有変数を読み取ります。

  • 1 つのスレッドが共有変数を変更すると、他のスレッドは変数の変更 (変更) を確認 (認識) できます

    これは真実です通常の変数と volatile 変数の両方
    • #違いは、volatile の特別なルールにより、volatile 変数の値が変更された後の新しい値が直ちにメイン メモリに同期されることです。 , volatile 変数は使用の直前にメイン メモリからリフレッシュされるため、volatile は複数のスレッド間での操作変数の可視性を保証しますが、通常の変数ではこれを保証できません。
    • #可視性を実現できる volatile キーワードに加えて、synchronized、Lock、
    final (immutable)
  • も可能

    #使用synchronized キーワード、同期メソッド/同期ブロック (Monitor Enter) の先頭で、共有変数を使用する場合、変数値がメイン メモリから作業メモリに更新されます (つまり、最新の値がメモリから読み取られます)。メインメモリからスレッドのプライベートワーキングメモリへ)、同期メソッド/同期ブロック(Monitor Exit)の最後で、ワーキングメモリ内の変数値がメインメモリに同期されます(つまり、値スレッドのプライベート ワーキング メモリ内のデータは、同期のためにメイン メモリに書き込まれます) .Lock インターフェイスの最も一般的に使用される実装である ReentrantLock (リエントラント ロック) を使用して、可視性を実現します。メソッドの先頭で lock.lock() メソッドを実行します。これは同期された開始位置 (Monitor Enter) と同じです。これらは同じセマンティクスを持ちます。つまり、共有変数を使用する場合、変数値はメイン メモリから作業メモリに読み取られ (つまり、最新の値がメイン メモリからスレッドのプライベート 作業メモリに読み取られます)、ロックはメソッドの最後のブロックで実行されます。同期された終了位置 (Monitor Exit) と同じセマンティクス、つまり、作業メモリ内の変数値をメイン メモリに同期します (つまり、スレッドのプライベート 作業メモリ内の値をメイン メモリに書き込みます)。メインメモリ)、同期)。

    final キーワードの可視性は、コンストラクターで初期化された後、final によって変更された変数を指します。また、「this」参照はコンストラクターで渡されません (「this」参照のエスケープは非常に危険です。他のスレッドは、この参照を通じて「半分だけ初期化された」オブジェクトにアクセスする可能性があります)、その後、他のスレッドは最終変数の値を確認できます。

以上がJava メモリ モデルは何をするのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。