1. ホーム
  2. java

シングルトンのダブルチェックロック

2023-11-29 21:34:04

質問

このコードでは、以下のようにダブルチェックロックを使用しています。私はいくつかのソースで多くの記事を読んだように、彼らは2つの同時実行スレッドが2つの異なるオブジェクトを作るのを防ぐため、ダブルチェックが有用であると言います。

public class DoubleCheckLocking {

    public static class SearchBox {
        private static volatile SearchBox searchBox;

        // private constructor
        private SearchBox() {}

        // static method to get instance
        public static SearchBox getInstance() {
            if (searchBox == null) { // first time lock
                synchronized (SearchBox.class) {
                    if (searchBox == null) {  // second time lock
                        searchBox = new SearchBox();
                    }
                }
            }
            return searchBox;
        }
}

上記のコードはまだあまり理解できていません。インスタンスがnullのときに2つのスレッドが一緒に同じ行を実行すると、何が問題なのでしょうか?

if (searchBox == null) {
                synchronized (SearchBox.class) {
                    if (searchBox == null) {
                        searchBox = new SearchBox();
                    }
                }
            }

これが表示されると、2つのスレッドはオブジェクトがnullであることを認識し、同期をとる。 もう一度確認すると、やはりNULLと表示されます。 .そして、2つの異なるオブジェクトを作成します。OOOPS。

私のために説明してください。私は何を間違って理解しているのでしょうか?

ありがとうございます。)

どのように解決するのですか?

いいえ、あなたは SearchBox.class にロックをかけているので、同期ブロックには一度に1つのスレッドしか入りません。ですから、最初のスレッドが入ると searchBox が NULL であることを発見し、それを生成して同期ブロックから離れ、次に 2 番目のスレッドがブロックに入ると searchBox が null でないことを発見します。 searchBox .

ダブルチェックパターンは、コードを実行するたびにロックを取得することを避けるために使用されます。もし呼び出しが同時に行われない場合、最初の条件は失敗し、コード実行はロックを実行しないので、リソースを節約することができます。