1. ホーム
  2. java

[解決済み] Java の静的イニシャライザはスレッドセーフか?

2022-05-28 11:49:22

質問

静的コードブロックを使って、レジストリ内のいくつかのコントローラを初期化しています。質問は、したがって、この静的コードブロックが、クラスが最初にロードされたときに一度だけ絶対に呼び出されることを保証できるでしょうか。このコードブロックがいつ呼ばれるかを保証できないことは理解していますが、クラスローダーが最初にロードするときだと思います。私は静的なコードブロックのクラスで同期することができると理解していますが、私の推測では、これは実際にとにかく何が起こるのでしょうか?

簡単なコード例は次のとおりです。

class FooRegistry {

    static {
        //this code must only ever be called once 
        addController(new FooControllerImpl());
    }

    private static void addController(IFooController controller) { 
        // ...
    }
}

とか、こうすればいいのか。

class FooRegistry {

    static {
        synchronized(FooRegistry.class) {
            addController(new FooControllerImpl());
        }
    }

    private static void addController(IFooController controller) {
        // ...
    }
}

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

Java の静的イニシャライザはスレッドセーフです(最初のオプションを使用してください)。

しかし、コードが正確に一度だけ実行されることを確実にしたい場合、クラスが単一のクラスローダーによってのみロードされることを確認する必要があります。静的な初期化はクラスローダーごとに一度だけ実行されます。