検索
ホームページJava&#&チュートリアル[Java 同時実行性との戦い]-----Java メモリ モデルの揮発性の分析

前のブログ [Fuck Java Concurrency] - volatile の実装原理の詳細な分析で、すでに volatile の特徴が説明されています。変数書き込み;

  1. volatile アトミック; i++ などの複合操作を除き、volatile は「メモリ バリア」を使用します。 volatile セマンティクスを実装する

  2. 次に、LZ は、happens before 原則と volatile メモリ セマンティクスを通じて volatile を導入します。

    揮発性とハプエンドビフォア
  3. このブログ [Deadly Java Concurrency] - Java Memory Model Happend-Before で、LZ は、happend-before がデータ競合があるかどうか、およびスレッドが安全かどうかを判断するための主な基礎であると説明しています。マルチスレッド環境での可視性を確保します。古典的な例を使用して、揮発性変数の読み取りと書き込みによって確立される前に発生する関係を分析してみましょう。

    public class VolatileTest {
    
        int i = 0;    volatile boolean flag = false;    //Thread A
        public void write(){
            i = 2;              //1
            flag = true;        //2
        }    //Thread B
        public void read(){        if(flag){                                   //3
                System.out.println("---i = " + i);      //4
            }
        }
    }

    happens-before の原則によれば、上記のプログラムでは次の関係が得られます。
  4. happens-before原則の揮発性によると: 2 happens-before 3;

happens-beforeの推移性によると: 1 happens-before 4

操作1と操作4にhappens-beforeがある場合関係がある場合、1 は 4 に表示される必要があります。一部の学生は、「操作 1 と操作 2 の順序を入れ替えてもよいのですが、それは可能ですか?」と尋ねるかもしれません。 LZ のブログを読んでいると、volatile は可視性を確保するだけでなく、並べ替えも禁止していることがわかります。したがって、volatile 変数を書き込む前にスレッド A に表示されていたすべての共有変数は、スレッド B が同じ volatile 変数を読み取った直後にスレッド B に表示されるようになります。

    volatile のメモリ セマンティクスとその実装
  • JMM では、スレッド間の通信は共有メモリを使用して実装されます。 volatile のメモリ セマンティクスは次のとおりです:

  • volatile 変数を書き込むと、JMM はスレッドに対応するローカル メモリ内の共有変数値をメイン メモリに即座にリフレッシュします。

    volatile 変数を読み取るとき、JMM はスレッドに対応するローカル メモリを無効に設定し、共有変数をメイン メモリから直接読み取ります

  • そのため、volatile の書き込みメモリ セマンティクスはメイン メモリに直接更新され、メモリ セマンティクスは読み取り値はメインメモリから直接読み取られます。

    それでは、揮発性メモリのセマンティクスはどのように実装されるのでしょうか?一般的な変数の場合は並べ替えられますが、揮発性変数の場合は並べ替えられません。これはメモリ セマンティクスに影響を与えるため、揮発性メモリ セマンティクスを実現するために、JMM は並べ替えを制限します。並べ替えのルールは次のとおりです。

  • 翻訳は次のとおりです。

最初の操作が揮発性読み取りの場合、2 番目の操作がどのようなものであっても、並べ替えることはできません。この操作により、揮発性読み取り後の操作がコンパイラーによって揮発性読み取りの前に並べ替えられなくなります。

2 番目の操作が揮発性書き込みである場合、最初の操作がどのようなものであっても、並べ替えることはできません。この操作により、揮発性書き込み前の操作がコンパイラーによって揮発性書き込みの後に並べ替えられなくなります。


最初の操作が揮発性書き込みで、2 番目の操作が揮発性読み取りである場合、並べ替えることはできません。


volatile の基本的な実装はメモリ バリアを挿入することですが、コンパイラが挿入されるメモリ バリアの総数を最小限に抑える最適な配置を見つけることはほとんど不可能であるため、JMM は保守的な戦略を採用します。以下のように:

  1. 各揮発性書き込み操作の前に StoreStore バリアを挿入します

  2. 各揮発性書き込み操作の後に StoreLoad バリアを挿入します

  3. 各揮発性読み取り操作の後に LoadLoad バリアを挿入します

LoadStore バリアを挿入します各揮発性読み取り操作の後

  • StoreStore バリアは、揮発性書き込みの前に、その前の通常の書き込み操作がすべてメイン メモリにフラッシュされていることを保証できます。

  • StoreLoad バリアの機能は、後続の揮発性読み取り/書き込み操作によって揮発性書き込みが並べ替えられるのを防ぐことです。
  • LoadLoad バリアは、プロセッサが上の揮発性読み取りと下の通常読み取りの順序を変更するのを防ぐために使用されます。

  • LoadStore バリアは、プロセッサが揮発性読み取りを上に、通常の書き込みを下に並べ替えることを防ぐために使用されます。
  • 上記の VolatileTest の例を分析してみましょう:

    public class VolatileTest {
        int i = 0;    
        volatile boolean flag = false;    
        public void write(){
            i = 2;
            flag = true;
        }    public void read(){        
        if(flag){
                System.out.println("---i = " + i); 
            }
        }
    }
  • volatile 命令のメモリ バリアの凡例を、例を通して少し示します。実際、Volatile のメモリ バリア挿入戦略は非常に保守的であり、揮発性の書き込み/読み取りメモリのセマンティクスが変更されない限り、コンパイラは特定の状況に応じて最適化し、不要なバリアを省略できます。以下は (Fang Tengfei の「The Art of Java Concurrent Programming」から抜粋):
  • public class VolatileBarrierExample {
        int a = 0;    
        volatile int v1 = 1;    
        volatile int v2 = 2;    
        void readAndWrite(){        
        int i = v1;     //volatile读
            int j = v2;     //volatile读
            a = i + j;      //普通读
            v1 = i + 1;     //volatile写
            v2 = j * 2;     //volatile写
        }
    }
最適化されていない例の図は次のとおりです:

上の図のどのメモリ バリア命令が冗長であるかを分析してみましょう

1

: これは絶対に保存しておかなければなりません

2: 以下のすべての通常の書き込みは、上記の揮発性読み取りで並べ替えることが禁止されています。ただし、2 番目の揮発性読み取りが存在するため、通常の読み取りは 2 番目の揮発性読み取りをバイパスできません。したがって、省略することもできます。

3: 以下に通常の読み方はないため、省略できます。

4: 予約済み

5: 予約済み

6: その後に揮発性の記述が続くた​​め省略可能

7: 予約済み

8: 予約済み

2、 3、6は省略可能で、概略図は以下の通りです:

[Java 同時実行性との戦い]-----Java メモリ モデルの揮発性の分析


上記は、[Deadly Java Concurrency] - 揮発性 Java メモリ モデルの分析の内容です。 PHP 中国語 Web サイト (www.php.cn) にアクセスしてください。


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。