Java静态初始化程序线程安全吗?

我正在使用静态代码块来初始化我拥有的注册表中的某些控制器。因此,我的问题是,我可以保证在首次加载该类时,该静态代码块仅被绝对调用一次吗?我知道我不能保证何时将调用此代码块,我猜测是在Classloader首次加载时。我意识到我可以在静态代码块中的类上进行同步,但是我想这实际上还是会发生什么吗?


简单的代码示例将是;


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) {

        // ...

    }

}


慕妹3242003
浏览 1069回答 3
3回答

慕侠2389804

这是可以用于延迟初始化的技巧enum Singleton {    INSTANCE;}或Java 5.0之前的版本class Singleton {   static class SingletonHolder {      static final Singleton INSTANCE = new Singleton();   }   public static Singleton instance() {      return SingletonHolder.INSTANCE;   }}由于SingletonHolder中的静态块将以线程安全的方式运行一次,因此您不需要任何其他锁定。仅当您调用instance()时,类SingletonHolder才会被加载

慕桂英546537

是的,有点一个static初始化仅被调用一次,所以由定义它是线程安全的-你需要在两个或两个以上的调用static初始化连得线程争。也就是说,static初始化器在许多其他方面令人困惑。确实没有指定调用它们的顺序。如果您有两个其static初始化程序相互依赖的类,这将非常令人困惑。而且,如果您使用一个类但不使用static初始化程序要设置的内容,则不能保证该类加载器将调用静态初始化程序。最后,请记住要同步的对象。我意识到这并不是您真正要问的问题,但是请确保您的问题不是真的在问您是否需要使addController()线程安全。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java