【发布时间】:2016-04-20 18:54:56
【问题描述】:
我需要提供以下容器的线程安全实现:
public interface ParameterMetaData<ValueType> {
public String getName();
}
public interface Parameters {
public <M> M getValue(ParameterMetaData<M> pmd);
public <M> void put(ParameterMetaData<M> p, M value);
public int size();
}
问题是 size 方法应该返回当前包含在 Parameters 实例中的准确个参数。所以,我的第一次尝试是尝试如下委派线程安全:
public final class ConcurrentParameters implements Parameters{
private final ConcurrentMap<ParameterMetaData<?>, Object> parameters =
new ConcurrentHashMap<>();
//Should represent the ACCURATE size of the internal map
private final AtomicInteger size = new AtomicInteger();
@Override
public <M> M getValue(ParameterMetaData<M> pmd) {
@SuppressWarnings("unchecked")
M value = (M) parameters.get(pmd);
return value;
}
@Override
public <M> void put(ParameterMetaData<M> p, M value){
if(value == null)
return;
//The problem is in the code below
M previous = (M) parameters.putIfAbsent(p, value);
if(previous != null)
//throw an exception indicating that the parameter already exists
size.incrementAndGet();
}
@Override
public int size() {
return size.intValue();
}
问题是我不能只在ConcurrentHashMap 实例上调用parameters.size() 来返回实际大小,因为该操作在没有锁定的情况下执行遍历,并且没有保证它将检索实际大小。在我的情况下这是不可接受的。所以,我决定维护包含大小的字段。
问题:是否有可能以某种方式委托线程安全并保持不变性?
【问题讨论】:
-
如果没有外部锁定,您无法获得比 ConcurrentHashMap 已经提供的更高的精度,因为您无法保证原子操作。
标签: java multithreading