问题描述
我想在Java中实现多线程的延迟初始化。
我有一些类型的代码:
I want to implement lazy initialization for multithreading in Java.
I have some code of the sort:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
Helper h;
synchronized(this) {
h = helper;
if (h == null)
synchronized (this) {
h = new Helper();
} // release inner synchronization lock
helper = h;
}
}
return helper;
}
// other functions and members...
}
我得到了双检查锁定被破坏声明。
我如何解决这个问题?
And I'm getting the the "Double-Checked Locking is Broken" declaration.
How can I solve this?
推荐答案
这里是有效的Java
Here is the idiom recommended in the Item 71: Use lazy initialization judiciously of Effective Java:
// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) { // First check (no locking)
synchronized(this) {
result = field;
if (result == null) // Second check (with locking)
field = result = computeFieldValue();
}
}
return result;
}
此代码可能显示有点复杂。
特别的,对本地
变量结果的需要可能不清楚。
这个变量的作用是确保
字段在普通
中只读一次,它已经被初始化了。
虽然不是绝对必要的,但是可以通过应用于
低级并发编程的标准,
提高性能和更多
。在
我的机器,上面的方法约
比没有本地变量的明显的
版本快25%。
This code may appear a bit convoluted. In particular, the need for the local variable result may be unclear. What this variable does is to ensure that field is read only once in the common case where it’s already initialized. While not strictly necessary, this may improve performance and is more elegant by the standards applied to low-level concurrent programming. On my machine, the method above is about 25 percent faster than the obvious version without a local variable.
版本1.5,双重检查
idiom没有可靠地工作,因为
volatile修饰符
的语义不够强大,不支持
[Pugh01]。内存模型在版本1.5中引入了
,解决了这个问题
[JLS,17,Goetz06 16]。今天,
double-check idiom是
选项的技术,用于延迟初始化
实例字段。虽然你可以应用
双重检查成语到静态
字段,没有理由
这样做:延迟初始化持有人
类成语是一个更好的选择。
Prior to release 1.5, the double-check idiom did not work reliably because the semantics of the volatile modifier were not strong enough to support it [Pugh01]. The memory model introduced in release 1.5 fixed this problem [JLS, 17, Goetz06 16]. Today, the double-check idiom is the technique of choice for lazily initializing an instance field. While you can apply the double-check idiom to static fields as well, there is no reason to do so: the lazy initialization holder class idiom is a better choice.
参考
- 版本
- 项目71:谨慎使用延迟初始化
这篇关于如何解决“双重锁定被破坏” Java的声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!