2015-01-07 4 views
2

Я пытаюсь создать поточно-структуру данных в Java, вдоль линий следующее:Синхронные вложенные коллекции в Java

public class A { 

    ConcurrentHashMap<String, Set<String>> subscriptions 

    private void addSubscription(String server, String client) { 
     Set<String> clients = subscriptions.get(server); 
     if (clients == null) { 
      clients = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); 
      subscriptions.put(server, agents); 
     } 
     clients.add(client); 
    } 

    private synchronized void removeSubscription(String server, String client) { 
     Set<String> clients = subscriptions.get(server); 
     if (clients != null) { 
      clients.remove(client); 
      if (clients.isEmpty()) { 
       subscriptions.remove(server, agents); 
      } 
     } 
    } 
} 

Тем не менее, кажется, что мне нужно добавить дополнительную синхронизацию (I «угадывая что-то, чтобы защитить доступ к наборам»). Есть ли более эффективная коллекция для использования здесь, или мне просто нужно добавить к ней соответствующую синхронизацию?

+1

Коллекции Google Guava имеют метод 'Multimaps.synchronizedSetMultimap()'. Я никогда не пробовал, но, похоже, именно то, что вы хотите. –

ответ

0

Что заставляет вас думать, что вам нужна дополнительная синхронизация? Я не понимаю, почему это так. Одна вещь, которую я бы изменил, заключается в том, что addSubscription должен проверить, нет ли набора для данного сервера и добавить его атомарно. Таким образом, можно избежать состояния гонки, когда два потока добавление клиента к тому же серверу:

Set<String> newClients = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); 
Set<String> clients = subscriptions.putIfAbsent(server, newClients); 
if(clients == null) clients = newClients; 
clients.add(client); 

Кроме того, я бы не удалить набор с карты после того, как он становится пустым. В противном случае возникает другое состояние гонки: кто-то мог добавить нового клиента сразу после того, как вы проверили размер и обнаружили, что он пуст, и вы собираетесь его выбросить. Просто позвольте пустому множеству остаться там, в этом нет большого вреда.

Смежные вопросы