Java:如何使用数组元素进行双重检查锁定?
-
29-09-2019 - |
题
这就是我的代码当前的样子:
private boolean[] isInitialized = new boolean[COUNT];
private void ensureInitialized(int i) {
if (! isInitialized[i]) {
initialize(i);
isInitialized[i] = true;
}
}
现在我想拥有线程安全。我知道Java中的双重检查锁定是“ Teh 3vilness !! 1”,但是自从 ensureInitialized
可能经常被称为,我不希望它同步。所以我正在考虑这样做:
private boolean[] isInitialized = new boolean[COUNT];
private void ensureInitialized(int i) {
if (! isInitialized[i]) {
synchronized (this) {
if (! isInitialized[i]) {
initialize(i);
isInitialized[i] = true;
}
}
}
}
现在,我该怎么做才能使此线程实际安全?
一些子问题:
- 制造
isInitialized
不需要挥发性,因为变量没有更改,对吗? - 阵列元素已更改,我该如何使这些动荡不安?
- 通常有更好的方法吗?
(还请注意,这是一种实例方法,因此静态初始器将无效)
解决方案
请注意,双重检查的Java实现称为“破碎模式”,因为它被证明为失败(例如,请参见 http://www.cs.umd.edu/~pugh/java/memorymodel/doublecheckedlocking.html)。为了解决仅使用原子操作。跟随示例如何构建线程安全单例:
static AtomicReferenceArray<Boolean> instance =
new AtomicReferenceArray<Boolean>(COUNT);
private void ensure(int i)
{
if(!instance.get(i) )
{
synchronized(this){
if( !instance.get(i) ){
initialize(i);
instance.set(i, true);
}
}
}
其他提示
您也可以考虑使用 Suppliers.memoize(Supplier<T> delegate)
从 番石榴图书馆.
不隶属于 StackOverflow