Я не уверен, что вы можете сделать это легко с семантикой MapConstraint . Вы можете сделать MapConstraint осведомленным о базовой карте, передав ей ссылку на карту во время построения:
MapConstraints.constrainedMap(map, new MyCustomMapConstraint(map));
Но это было бы ужасно / рискованно. Кто-то мог ошибочно сделать:
MapConstraint constraint = new MyCustomMapConstraint(firstMap);
Map constrainedMap = MapConstraints.constrainedMap(secondMap, constraint);
Кроме того, это не решит проблему синхронизации.
Если бы я это сделал, я бы использовал метод putIfAbsent, предоставленный ConcurrentMap. Я хотел бы создать оболочку ConcurrentMap, используя ForwardingConcurrentMap:
public class ProtectionistMap<K, V> extends ForwardingConcurrentMap<K, V> {
private final ConcurrentMap<K, V> delegate;
public ProtectionistMap(ConcurrentMap<K, V> delegate) {
this.delegate = checkNotNull(delegate);
}
@Override
protected ConcurrentMap<K, V> delegate() {
return delegate;
}
@Override
public V put(K key, V value) {
V result = putIfAbsent(key, value);
// The second part of the test is necessary when a map may contain null values...
if (result != null || value == null && containsKey(key)) {
throw new IllegalArgumentException("Map already had an entry for key " + key);
}
return result;
}
@Override
public void putAll(Map<? extends K, ? extends V> map) {
standardPutAll(map);
}
}