返回信息流public class FinalWrapper<T>
{
public final T value;
public FinalWrapper(T value) { this.value = value; }
}
public class Foo
{
private FinalWrapper<Helper> helperWrapper = null;
public Helper getHelper()
{
FinalWrapper<Helper> wrapper = helperWrapper;
if (wrapper == null)
{
synchronized(this)
{
if (helperWrapper ==null)
helperWrapper = new FinalWrapper<Helper>( new Helper() );
wrapper = helperWrapper;
}
}
return wrapper.value;
}
}
为什么说:The local variable wrapper is required for correctness.??不使用这个wrapper会有什么问题呢?等大神们指教[ema13]
这是一条镜像帖。来源:北邮人论坛 / java / #17535同步于 2011/3/17
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于final的安全发布
yanzhao
2011/3/17镜像同步6 回复
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
没太看懂你的意思
The local variable wrapper is required for correctness
这句话是在哪看到的?
你是想问为什么判断两次wrapper是否为空么?
【 在 yanzhao (灰狼坏坏) 的大作中提到: 】
: public class FinalWrapper<T>
: {
: public final T value;
: ...................
不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址
http://en.wikipedia.org/wiki/Double-checked_locking
这篇文章对双检查锁有详细的描述
里面有回答你的问题
http://www.ibm.com/developerworks/java/library/j-dcl.html
【 在 yanzhao (灰狼坏坏) 的大作中提到: 】
: 不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址
: http://en.wikipedia.org/wiki/Double-checked_locking
其实原因就是在于helperWrapper = new FinalWrapper<Helper>( new Helper() ); 这个并不是一个原子操作,如果在这个操作过程中,线程被打断,helperWrapper这个变量已经被标记为非null,但是对象还没有初始化完成,这时候有另外的线程调用GET方法,检测到helperWrapper已经不是null,就开始使用,但是这个时候实际上并没有完成初始化,这时候就会有问题
【 在 yanzhao (灰狼坏坏) 的大作中提到: 】
: 不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址
: http://en.wikipedia.org/wiki/Double-checked_locking
假设像你说的,在helperWrapper处于未初始化完全的状态,另一个线程去访问会出现问题,但是像在程序里面写的,加上一个本地变量wrapper也不会改变这种状况啊,wrapper=helperWrapper 也是一个非null的值,也可以访问到一个未初始化完全的状态!
而且在这篇文章里我看到似乎也不能访问到未初始化完成的helperWrapper对象,因为它只有一个标记为final的字段,在初始化完全之前helperWrapper对象是不可见的,也就不存在你这儿提到的问题吧。
http://sunyimaying0925-gmail-com.javaeye.com/blog/882781
【 在 ox 的大作中提到: 】
: 其实原因就是在于helperWrapper = new FinalWrapper<Helper>( new Helper() ); 这个并不是一个原子操作,如果在这个操作过程中,线程被打断,helperWrapper这个变量已经被标记为非null,但是对象还没有初始化完成,这时候有另外的线程调用GET方法,检测到helperWrapper已经不是null,就开始使用,但是这个时候实际上并没有完成初始化,这时候就会有问题
: 【 在 yanzhao (灰狼坏坏) 的大作中提到: 】
: : 不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址
: ...................
【 在 yanzhao 的大作中提到: 】
: 假设像你说的,在helperWrapper处于未初始化完全的状态,另一个线程去访问会出现问题,但是像在程序里面写的,加上一个本地变量wrapper也不会改变这种状况啊,wrapper=helperWrapper 也是一个非null的值,也可以访问到一个未初始化完全的状态!
加上一个本地变量能解决这个问题,因为在helperWrapper初始化完成之前wrapper一直都是null。wrapper=helperWrapper是在helperWrapper= new FinalWrapper<Helper>( new Helper() )之后执行的,也就是说只有在new的过程完全结束后才能执行到wrapper=helperWrapper,之前wrapper一直为null;
: 而且在这篇文章里我看到似乎也不能访问到未初始化完成的helperWrapper对象,因为它只有一个标记为final的字段,在初始化完全之前helperWrapper对象是不可见的,也就不存在你这儿提到的问题吧。
“因为它只有一个标记为final的字段,在初始化完全之前helperWrapper对象是不可见的”,没看懂这句话是啥意思。
在多线程并发的时候这种情况是完全可以出现的,一个线程在new FinalWrapper的过程中(但还未完),另一个线程看到的helperWrapper就已经不是null了,如果后面这个线程直接去使用helperWrapper对象就有可能出现不正确的行为,为了保险起见采用了一个局部变量。
: http://sunyimaying0925-gmail-com.javaeye.com/blog/882781
: ...................