作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一种预感,即使用 holder 惯用法而不将 holder 字段声明为 final 不是线程安全的(由于不变性在 Java 中的工作方式)。有人可以证实这一点(希望有一些消息来源)吗?
public class Something {
private long answer = 1;
private Something() {
answer += 10;
answer += 10;
}
public int getAnswer() {
return answer;
}
private static class LazyHolder {
// notice no final
private static Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
编辑:我绝对想要来源声明,而不仅仅是像“它有效”这样的断言——请解释/证明它是安全的
EDIT2:为了让我的观点更清楚一点,我做了一点修改——我能确定 getAnswer() 方法将返回 21 而不管调用线程吗?
最佳答案
class initialization procedure保证如果使用静态初始值设定项(即 static variable = someValue;
)设置静态字段的值,则该值对所有线程可见:
10 - If the execution of the initializers completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.
关于您的编辑,让我们想象一下有两个线程 T1 和 T2 的情况,从挂钟的角度来看按该顺序执行:
Something s = Something.getInstance();
Something s = Something.getInstance(); i = s.getAnswer();
那么你有:
Something INSTANCE = new Something();
,初始化answer
,T1释放LCINSTANCE
然后读取answer
。因此,由于 LC
锁,您可以看到在对 answer
的写入和读取之间有一个正确的先行发生关系。
关于java - 没有 final 修饰符,Initialization On Demand Holder 成语线程安全吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20995036/
我是一名优秀的程序员,十分优秀!