我想在一个类中有一个静态字段,以便在加载另一个类时自动进行初始化。

像这样:

class ServiceBase {
    static Object lock = new Object();
    static ServiceBase service;
    static void setService(ServiceBase service) {
        synchronized (lock) {
            ServiceBase.service = service;
            lock.notifyAll();
        }
    }
    void f() throws Exception {
        synchronized (lock) {
            while (service == null){
                lock.wait();
            }
       }
       //use service
   }
}

class ServiceImpl extends ServiceBase {
    static {
        ServiceBase.setService(ne ServiceImpl());
    }
}


问题在于f在加载ServiceImpl之前被调用,它挂在死锁中。

初始化服务实例的最佳方法是什么? (我不能使用Spring或其他大型框架)

最佳答案

您的方法过于复杂。您无需担心同步或任何同步问题。

最明显的简化是将Service实例作为构造函数参数传递给ServiceBase

class ServiceBase {
  private final Service service;

  ServiceBase(Service service) {
    this.service = checkNotNull(service);
  }

  void f() {
    // service is guaranteed to be present.
  }
}


这样,您永远无法在非空服务可用之前实际调用f()

如果您担心每次都希望使用相同的ServiceImpl实例,请创建用于获取ServiceBaseProvider实例的ServiceBase类,而不是直接构造它们:

class ServiceBaseProvider {
  private static ServiceImpl INSTANCE = new ServiceImpl();

  static ServiceBase getInstance() {
    return new ServiceBase(INSTANCE);
  }
}


或者,当然,可以在需要的地方注入ServiceBase的相同实例,这使得(例如)在测试过程中注入模拟实例更加容易。

关于java - 等待静态初始化器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35034981/

10-09 09:35