Нет, Set
является изменяемым, мутированным и доступным вне замка.Намного лучше использовать неизменяемый Set
s.
public void addProxyRole(REGISTRY reg, CONTACT_ROLES role) {
Set<CONTACT_ROLES> old =
proxyRoles.putIfAbsent(reg, Collections.singleton(role));
if (old == null) {
return;
}
for (;;) {
Set<CONTACT_ROLES> set = new HashSet<>(old);
set.add(role);
if (proxyRoles.replace(reg, old, Collections.unmodifiableSet(set))) {
return;
}
old = proxyRoles.get(reg);
}
}
(Отказ от ответственности: это переполнение стека, не скомпилировано или протестировано.)
Альтернативой циклу было бы использование потокаsafe Set
, но это также потребует большей осторожности при использовании (например, вы не можете просто перебрать его).
public void addProxyRole(REGISTRY reg, CONTACT_ROLES role) {
Set<CONTACT_ROLES> set = proxyRoles.get(reg);
if (set == null) {
Set<CONTACT_ROLES> newSet = Collections.synchronizedSet(new HashSet<>());
Set<CONTACT_ROLES> old = proxyRoles.putIfAbsent(reg, newSet);
set = old==null ? newSet : old;
}
set.add(role);
}
A CopyOnWriteArraySet
, скажем, также возможно.