Javaダブルチェックロックモードとは何ですか

WBOY
リリース: 2023-05-19 15:29:49
転載
1410 人が閲覧しました

原因

プロジェクトで PMD 静的コード検出を実行しているときにこのような問題が発生しました

部分的に作成されたオブジェクトは、使用時にダブル チェック ロック パターンによって返される可能性があります最適化 JRE は、参照が指すオブジェクトのコンストラクターを呼び出す前に、baz 変数への参照を割り当てることができます。

注: Java 5 では、次のように宣言すると、二重チェックされたロックを機能させることができます

#ダブルチェック ロック モードを使用すると、不完全に初期化されたオブジェクトが返される可能性があります。部分的に初期化されたオブジェクトの概念に疑問を持つ人もいるかもしれません。分析を続けてください。

二重チェック ロック モードとは

<code>public static Singleton getSingleton() {<br>    if (instance == null) {                        <br>        synchronized (Singleton.class) {<br>            if (instance == null) {                 <br>                instance = new Singleton();<br>            }<br>        }<br>    }<br>    return instance ;<br>}</code> 
ログイン後にコピー

同期されたコード ブロックの内側と外側の両方で、インスタンス = と判断されることがわかります。 = null の場合、同期コードブロック外で複数のスレッドが同時に if 判定に入る可能性があるためであり、同期コードブロック内で null 判定を行わないと複数のインスタンスが初期化される可能性があります。

問題点

この書き方は完璧に見えますが、問題があるか、完璧であることを保証するものではありません。主な理由は、instance = new Singleton(); がアトミックな操作ではないことです。

オブジェクトの作成は 3 つの部分に分けることができます:

<code>1.分配对象的内存空间<br>2.初始化对象<br>3.设置instance指向刚分配的内存地址<br>当instance指向分配地址时,instance是不为null的</code> 
ログイン後にコピー
ただし、ステップ 2 と 3 の間で順序が変更され、オブジェクトの作成順序が 1-3-2 になる場合があります。 :

スレッド A が初めてオブジェクト Singleton を作成し、オブジェクトの作成順序は 1-3-2 です;
インスタンスにメモリを割り当てた後、スレッド B が来て getSingleton() メソッドを呼び出します
This インスタンス == null 判定の場合、インスタンスは null ではないことがわかります。
ただし、この時点ではインスタンスはオブジェクトを初期化しておらず、スレッド B は初期化されていないオブジェクトを返すことに注意してください。スレッド B がインスタンスを使用するときに問題が発生する場合がありますが、これは二重チェック ロックの問題です。

volatile を使用する

上記の問題については、インスタンスを volatile として宣言することで上記の問題を解決できます

<code>public class Singleton{<br>    private volatile static Singleton instance;<br>    public static Singleton getSingleton() {<br>        if (instance == null) {                        <br>            synchronized (Singleton.class) {<br>                if (instance == null) {                 <br>                    instance = new Singleton();<br>                }<br>            }<br>        }<br>        return instance ;<br>    }<br>}</code> 
ログイン後にコピー
ただし、JDK5 バージョン以降で使用する必要があります。

静的内部クラス

<code>public class Singleton {  <br>    private static class SingletonHolder {  <br>        private static final Singleton INSTANCE = new Singleton();  <br>    }  <br>    private Singleton (){}  <br>    public static final Singleton getInstance() {  <br>        return SingletonHolder.INSTANCE; <br>    }  <br>}</code>
ログイン後にコピー

現在推奨されている記述方法は、スレッド安全性の問題を発生させずに遅延読み込みを実現できる静的内部クラスを使用することです。また、同期のオーバーヘッドも軽減されます。

以上がJavaダブルチェックロックモードとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!