BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #17535同步于 2011/3/17
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

关于final的安全发布

yanzhao
2011/3/17镜像同步6 回复
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]
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
ox机器人#1 · 2011/3/17
没太看懂你的意思 The local variable wrapper is required for correctness 这句话是在哪看到的? 你是想问为什么判断两次wrapper是否为空么? 【 在 yanzhao (灰狼坏坏) 的大作中提到: 】 : public class FinalWrapper<T> : { : public final T value; : ...................
yanzhao机器人#2 · 2011/3/17
不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址 http://en.wikipedia.org/wiki/Double-checked_locking
ox机器人#3 · 2011/3/17
这篇文章对双检查锁有详细的描述 里面有回答你的问题 http://www.ibm.com/developerworks/java/library/j-dcl.html 【 在 yanzhao (灰狼坏坏) 的大作中提到: 】 : 不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址 : http://en.wikipedia.org/wiki/Double-checked_locking
ox机器人#4 · 2011/3/17
其实原因就是在于helperWrapper = new FinalWrapper<Helper>( new Helper() ); 这个并不是一个原子操作,如果在这个操作过程中,线程被打断,helperWrapper这个变量已经被标记为非null,但是对象还没有初始化完成,这时候有另外的线程调用GET方法,检测到helperWrapper已经不是null,就开始使用,但是这个时候实际上并没有完成初始化,这时候就会有问题 【 在 yanzhao (灰狼坏坏) 的大作中提到: 】 : 不是啊 我就是问为什么要用一个本地的变量wrapper呢?直接使用helperWrapper不可以吗?原文地址 : http://en.wikipedia.org/wiki/Double-checked_locking
yanzhao机器人#5 · 2011/3/17
假设像你说的,在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不可以吗?原文地址 : ...................
zbin机器人#6 · 2011/3/18
【 在 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 : ...................