目次
1. はじめに
2. 問題の回復
(1) 関連する変数
1. 結果予測
2. 命令の再配置
(2) New でオブジェクトを作成します
1. 解析と作成のプロセス
3. 命令の並び替えへの対応
2. マルチスレッド環境での命令の再配置
上記では、2 つの典型的なマルチスレッド環境での命令の再配置について説明し、その悪影響を分析し、それぞれ対策を示しました。
ホームページ Java &#&チュートリアル マルチスレッド環境での Java 命令の並べ替えを解決する方法

マルチスレッド環境での Java 命令の並べ替えを解決する方法

Apr 19, 2023 pm 03:40 PM
java

1. はじめに

命令の再配置は、シングルスレッド環境ではプログラムの実行効率の向上に役立ち、プログラムに悪影響を及ぼしませんが、マルチスレッド環境では、命令の再配置は、プログラムに驚きをもたらす、予期しないエラー。

2. 問題の回復

(1) 関連する変数

以下は命令の並び替えを完全に回復できる例です。

public class D {
    static Integer a;
    static Boolean flag;
    
    public static void writer() {
        a = 1;
        flag = true;
    }
    
    public static void reader() {
        if (flag != null && flag) {
            System.out.println(a);
            a = 0;
            flag = false;
        }
    }
}
ログイン後にコピー
1. 結果予測

reader メソッドは、flag 変数が true の場合にのみ、変数 a をコンソールに出力します。価値。

writer メソッドは、まず変数 a の代入演算を実行し、次に変数 flag の代入演算を実行します。

上記の分析ロジックに従う場合、コンソールに出力される結果はすべて 1 である必要があります。

2. 命令の再配置

コードに命令の再配置がない場合、flag 変数が true の場合、変数 a は 1 でなければなりません。 。

上記のコードでは、変数 a と変数 flag に関する両方のメソッド クラスで命令の再配置があります。

public static void writer() {
    a = 1;
    flag = true;
}
ログイン後にコピー

ログ出力を観察すると、多数の 0 出力があることがわかりました。

writer メソッド内で命令の再配置が発生すると、flag 変数が最初に割り当てを完了します。このとき、現在のスレッドが中断されると、他のスレッドも中断されます。 reader メソッドを呼び出し、flag 変数が true であることを検出し、変数 a の値を出力します。この時点で、コンソールには期待値を超える結果が表示されます。

(2) New でオブジェクトを作成します

new キーワードを使用してオブジェクトを作成する場合、非アトミックな操作であるため、命令の再配置が発生します。マルチスレッド環境への影響。

public class Singleton {
    private static UserModel instance;
    
    public static UserModel getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new UserModel(2, "B");
                }
            }
        }
        return instance;
    }
}

@Data
@AllArgsConstructor
class UserModel {
    private Integer userId;
    private String userName;
}
ログイン後にコピー
1. 解析と作成のプロセス
  • キーワード new を使ってオブジェクトを作成するのですが、大まかに次のようなプロセスに分かれます。

    ## スタック スペースに参照アドレスを作成します。
  • #クラス ファイルをテンプレートとして使用して、ヒープ スペース オブジェクトにメモリを割り当てます。

  • #メンバー変数の初期化

  • #コンストラクターを使用して初期化
  • ##参照値を左側の記憶変数に代入
  • #2. 並べ替えプロセスの分析

  • 上記の例では、最初のスレッドが同期されたコード ブロックに入り、オブジェクトの作成を開始すると仮定します。作成プロセスが中断され、スタック領域に参照アドレスが作成された後、参照値が左側の記憶変数に割り当てられ、その後 CPU スケジューリング タイム スライスの枯渇により割り込みが発生したように見える場合があります。
  • 後続のスレッドで

    instance
  • 変数が空ではないことが検出されると、その変数が直接使用されます。シングルトン オブジェクトはインスタンス化されないため、これらを直接使用すると予期しない結果が生じます。
3. 命令の並び替えへの対応

(1) AtomicReference アトミック クラス

アトミック クラスを使用して、その特性を利用して関連する変数のセットをオブジェクトにカプセル化します。アトミックな操作を実現し、コマンドの再配置の問題を効果的に回避します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>@Data @NoArgsConstructor @AllArgsConstructor public class ValueModel { private Integer value; private Boolean flag; }</pre><div class="contentsignin">ログイン後にコピー</div></div>アトミック クラスは、マルチスレッド環境で命令を並べ替える場合に推奨されるソリューションです。理解しやすいだけでなく、スレッド間で使用される非ヘビーウェイト ミューテックスは比較的効率的です。

public class E {
    private static final AtomicReference<ValueModel> ar = new AtomicReference<>(new ValueModel());
    
    public static void writer() {
        ar.set(new ValueModel(1, true));
    }
    
    public static void reader() {
        ValueModel valueModel = ar.get();
        if (valueModel.getFlag() != null && valueModel.getFlag()) {
            System.out.println(valueModel.getValue());
            ar.set(new ValueModel(0, false));
        }
    }
}
ログイン後にコピー

関連する変数のグループが命令の再配置を受ける場合、アトミック操作クラスを使用する方が良い解決策です。

(2) volatile キーワード

public class Singleton {
    private volatile static UserModel instance;
    
    public static UserModel getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new UserModel(2, "B");
                }
            }
        }
        return instance;
    }
}

@Data
@AllArgsConstructor
class UserModel {
    private Integer userId;
    private String userName;
}
ログイン後にコピー

4. 命令の再配置についての理解

1. 命令の再配置が広く普及している

命令の再配置 配置は整っていないJava プログラムに限定されますが、実際には、ソフトウェアから CPU ハードウェアに至るまで、さまざまなコンパイラで命令の再配置操作が行われます。命令の再配置は、シングル スレッド プログラムのパフォーマンスの最適化です。命令の再配置によって、シングル スレッド環境での順次プログラムの実行で期待される結果が変わるわけではないことは明らかです。

2. マルチスレッド環境での命令の再配置

上記では、2 つの典型的なマルチスレッド環境での命令の再配置について説明し、その悪影響を分析し、それぞれ対策を示しました。

関連する変数の場合は、まずそれらをオブジェクトにカプセル化してから、アトミック クラスを使用して操作します。

新しいオブジェクトの場合は、volatile キーワードを使用しますオブジェクトは、ターゲットを変更できます。

  • 3. 同期ロックは、並べ替えとは何の関係もありません。

  • 同期ロックにより、スレッドが相互接続を通じて順序どおりに特定のコード ブロックにアクセスできるようになります。除外ロック。コード ブロック内のコードは、通常、コンパイラによって実装された戦略に従って並べ替えられます。
  • 同期ロックを使用すると、マルチスレッド環境での並べ替えによる悪影響を回避できますが、ミューテックス ロックによって生じるスレッドのオーバーヘッドが比較的大きいため、お勧めできません。

同期ブロックでの非アトミック操作でも命令の再配置が発生する可能性があります

以上がマルチスレッド環境での Java 命令の並べ替えを解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

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

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

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

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

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

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

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

See all articles