java中的同步嵌套集合

时间:2015-01-07 02:18:27

标签: java multithreading collections java.util.concurrent

我试图在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);
            }
        }
    }
}

但是,似乎我需要添加额外的同步(我猜测了一些东西来保护访问集合)。有没有更好的集合在这里使用,或者我只需要为此添加适当的同步?

1 个答案:

答案 0 :(得分: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);

另外,我不会在地图变空之后从地图中删除它。否则会出现另一种竞争条件:有人可能在您检查了大小之后添加了一个新客户端并发现它是空的,并且您要将其丢弃。只要把空套放在那里,就不会有太大的危害。