为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕妹3242003 2019-10-15 15:59:19
我正在使用静态代码块来初始化我拥有的注册表中的某些控制器。因此,我的问题是,我可以保证在首次加载该类时,该静态代码块仅被绝对调用一次吗?我知道我不能保证何时将调用此代码块,我猜测是在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) {        // ...    }}
查看完整描述

3 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

这是可以用于延迟初始化的技巧


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才会被加载


查看完整回答
反对 回复 2019-10-15
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

是的,有点

一个static初始化仅被调用一次,所以由定义它是线程安全的-你需要在两个或两个以上的调用static初始化连得线程争。

也就是说,static初始化器在许多其他方面令人困惑。确实没有指定调用它们的顺序。如果您有两个其static初始化程序相互依赖的类,这将非常令人困惑。而且,如果您使用一个类但不使用static初始化程序要设置的内容,则不能保证该类加载器将调用静态初始化程序。

最后,请记住要同步的对象。我意识到这并不是您真正要问的问题,但是请确保您的问题不是真的在问您是否需要使addController()线程安全。


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 1061 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信