Обновить карту / установить и проверить размер атомарно - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть следующий метод:

private static HashSet<Integer> ids = new HashSet<>();  
public static void someMethod(SomeObject o) {  
  // some code  

 ids.add(o.getId());   
 if(ids.size() > 10) {  
   // do something  
 }  
 else {  
  // do something else  
 }  
}  

Простой способ сделать этот метод безопасным для потока - добавить ключевое слово synchronized.
Мне было интересно, если уже есть какой-то более подходящий способ добавить элемент в карту / набор и проверить размер атомарно

1 Ответ

0 голосов
/ 06 сентября 2018

Такого не существует, как сказано в комментариях, даже ConcurrentHashMap вам не поможет.

Будьте очень осторожны, чтобы не попасться в ловушку анти-паттерна «проверяй, чем действовать». Так, например, не делать:

 Set<Integer> syncIds = Collections.synchronizedSet(ids);
 syncIds.add(o.getId())  
 if(ids.size() > 10) {....}

Как отдельные операции, они действительно потокобезопасны, но как составные операции они не являются.

Имейте в виду, что, поскольку вы обновляете это HashSet под блокировкой, при чтении это должно быть сделано под той же блокировкой , вот как происходит до работает. Так что если вы выставите метод:

public Set<Integer> getIds(){
    return ids;
}

Чтобы это работало правильно, и вы не столкнулись с неожиданностями, этот метод также должен быть синхронизирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...