我有为延迟初始化和存储创建不需要线程安全的对象而设计的类。这是代码:
class SyncTest {
private static final Object NOT_INITIALIZED = new Object();
private Object object;
/**
* It's guaranteed by outer code that creation of this object is thread safe
* */
public SyncTest() {
object = NOT_INITIALIZED;
}
public Object getObject() {
if (object == NOT_INITIALIZED) {
synchronized (NOT_INITIALIZED) {
if (object == NOT_INITIALIZED) {
final Object tmpRef = createObject();
object = tmpRef;
}
}
}
return object;
}
/**
* Creates some object which initialization is not thread safe
* @return required object or NOT_INITIALIZED
* */
private Object createObject() {
//do some work here
}
}
这里final
变量tmpRef
用于在将创建的对象分配给检查变量之前存储它object
。这在测试中有效,但我不能肯定地说它是正确的,并且不会被编译器优化。可以使用这种方法还是object
必须将字段声明为volatile
?
包装类的变体也被认为是行
final Object tmpRef = createObject();
必须用这个替换:
Object tmpRef = new FinalWrapper(createObject()).getVal();
包装类如下所示:
private class FinalWrapper {
private final Object val;
public FinalWrapper(Object val) {
this.val = val;
}
public Object getVal() {
return val;
}
}
可以在多线程环境中安全地使用其中一些示例(尤其是具有最终本地字段的变体)吗?