我试图在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);
}
}
}
}
但是,似乎我需要添加额外的同步(我猜测了一些东西来保护访问集合)。有没有更好的集合在这里使用,或者我只需要为此添加适当的同步?
答案 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);
另外,我不会在地图变空之后从地图中删除它。否则会出现另一种竞争条件:有人可能在您检查了大小之后添加了一个新客户端并发现它是空的,并且您要将其丢弃。只要把空套放在那里,就不会有太大的危害。