我想在一个类中有一个静态字段,以便在加载另一个类时自动进行初始化。
像这样:
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/