マルチスレッドにおけるVolatileキーワードの使用法と機能


欠点は、指摘していただければ幸いです。


揮発性キーワード
public class SingleCase {
//双检锁的对象必须要用volatile修饰,不然因为指令重排导致第一个判断为空时,将未初始化的对象
//返回。
 private static volatile SingleCase instance2;

public static SingleCase getInstance2(){
    if(instance2 == null){
        synchronized(SingleCase.lass){
            if(instance2 == null){
                instance2 = new SingleCase();
            }
        }
    }
    return instance2;
}
}
ダブルチェックされたロックオブジェクトはvolatileで変更する必要があります。そうしないと、命令の再配置により最初の判断が空になったときに、初期化されていないオブジェクトが返されます。
前の記事の スレッドセーフ、synchronizedキーワード(リエントラントロック)の他の基本的な特性 、特定の問題の例は、作成されたオブジェクトが完全にinstance2を後に初期化されることを確実にする方法です。
これは今日皆さんと一緒に勉強する予定です。上記のコードは誤って記述されており、理由は間違っています。 命令の再配置の最適化 により、単純な対象オブジェクトを初期化し、オブジェクトアドレスをインスタンスフィールドに割り当てる順序が、Javaコードで記述された順序と異なる場合があるためです。 。
たとえば、スレッドAがシングルトンオブジェクトを作成すると、コンストラクターが呼び出される前に、オブジェクトにメモリ空間が割り当てられ、オブジェクトがデフォルト値に設定されます。この時点で、スレッドAは割り当てられたメモリアドレスをインスタンスフィールドに割り当てることができますが、オブジェクトが初期化操作を完了していない可能性があります。スレッドBがnewInstance()メソッドを呼び出すと、その結果、完全なシングルトンオブジェクトが初期化され、システムが異常動作します。
上記の問題を解決するために、 volatile フィールド を使用してインスタンスフィールド変更できます。ここでのvolatileキーワードの意味は、 命令の並べ替えの最適化 禁止 する こと です(別の役割は、メモリの可視性提供することです )。これにより、インスタンスフィールドが初期化されるときに、シングルトンオブジェクトが完全に初期化されます。

volatileキーワードの役割は、スレッドのプライベートデータスタックから変数の値を取得するのではなく、パブリックスタックから変数の値を強制することです。
図:

1.キーワードvolatileはスレッド同期の軽量実装であり、パフォーマンスは同期よりも優れており、volatileは変数でのみ変更でき、同期はメソッドやコードブロックなどを変更できます。
2、多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。
3、volatile可以保证数据的可见性,但不可以保证原子性,而synchronized可以保证原子性,也可以间接保证可见性,因为他会将私有内存和公共内存中的数据做同步。
4、volatile解决 的是变量在多个线程之间的可见性,而synchronized解决的是多个线程之间访问资源的同步性。

发布了26 篇原创文章 · 获赞 0 · 访问量 9935

おすすめ

転載: blog.csdn.net/weixin_38246518/article/details/78747246