实现 线程安全 延迟初始化的一些推荐方法是什么?例如,
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
原文由 mre 发布,翻译遵循 CC BY-SA 4.0 许可协议
实现 线程安全 延迟初始化的一些推荐方法是什么?例如,
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
原文由 mre 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您使用的是 Apache Commons Lang ,那么您可以使用 ConcurrentInitializer 的变体之一,例如 LazyInitializer 。
例子:
ConcurrentInitializer<Foo> lazyInitializer = new LazyInitializer<Foo>() {
@Override
protected Foo initialize() throws ConcurrentException {
return new Foo();
}
};
您现在可以安全地获取 Foo(仅初始化一次):
Foo instance = lazyInitializer.get();
如果您使用的是 Google 的 Guava :
Supplier<Foo> fooSupplier = Suppliers.memoize(new Supplier<Foo>() {
public Foo get() {
return new Foo();
}
});
然后通过 Foo f = fooSupplier.get();
调用它
来自 Suppliers.memoize javadoc :
返回一个供应商,它缓存在第一次调用 get() 期间检索到的实例,并在后续调用 get() 时返回该值。返回的供应商是 线程安全的。委托的 get() 方法将 最多被调用一次。如果 delegate 是之前调用 memoize 创建的实例,则直接返回。
原文由 Kenston Choi 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
对于单例,有一个优雅的解决方案,将任务委托给 JVM 代码进行静态初始化。
看
http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
以及 Crazy Bob Lee 的这篇博文
http://blog.crazybob.org/2007/01/lazy-loading-singletons.html