Я проектирую поточно-безопасный контейнерный класс под названием ConcurrentParamters
. вот что я обычно пишу:Почему не разрешены изменчивые конечные поля?
Интерфейсы:
public interface Parameters {
public <M> M getValue(ParameterMetaData<M> pmd);
public <M> void put(ParameterMetaData<M> p, M value);
public int size();
}
public interface ParameterMetaData<ValueType> {
public String getName();
}
Реализация:
public final class ConcurrentParameters implements Parameters{
private final Map<ParameterMetaData<?>, Object> parameters;
private final volatile AtomicInteger size; //1, Not compile
{
size = new AtomicInteger();
parameters = new ConcurrentHashMap<>();
}
public static Parameters emptyParameters(){
return new ConcurrentParameters();
}
@Override
public <M> M getValue(ParameterMetaData<M> pmd) {
M value = (M) parameters.get(pmd);
return value;
}
@Override
public <M> void put(ParameterMetaData<M> p, M value){
parameters.put(p, value);
size.incrementAndGet();
}
@Override
public int size() {
return size.intValue();
}
}
Я попытался сделать AtomicInteger
поле, представляющее размер окончательной, чтобы гарантировать, что ни один метод не может изменить поле poinitng к другому объекту, а также инициализировать его duriong.
Но поскольку контейнер будет доступен одновременно, мне нужно, чтобы в любой нити наблюдались изменения, сделанные другим. Итак, я попытался объявить его volatile
, а также для того, чтобы избежать ненужных synchronization
(мне не нужно взаимное исключение).
Я не компилировал. Зачем? Есть ли причина? Не имеет смысла декальрировать поле таким образом? Я думал, что это будет неприемлемо ... Может, это наследуется небезопасно?
На самом деле, я думал, что visilibilty тоже относится к состоянию объекта. Это о назначении .... –