java 中的同步嵌套集合
Synchronized nested collections in 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);
}
}
}
}
但是,我似乎需要添加额外的同步(我猜是为了保护对集合的访问)。有没有更好的集合可以在这里使用,还是我只需要为此添加适当的同步?
是什么让您认为您需要额外的同步?我不明白为什么会这样。
我要更改的一件事是 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);
此外,我不会在地图变空后将其从地图中删除。否则会出现另一种竞争条件:有人可能刚刚在您检查大小并发现它是空的之后添加了一个新客户端,而您打算将其丢弃。就让空集留在那里,这没什么坏处。
我正尝试在 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);
}
}
}
}
但是,我似乎需要添加额外的同步(我猜是为了保护对集合的访问)。有没有更好的集合可以在这里使用,还是我只需要为此添加适当的同步?
是什么让您认为您需要额外的同步?我不明白为什么会这样。
我要更改的一件事是 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);
此外,我不会在地图变空后将其从地图中删除。否则会出现另一种竞争条件:有人可能刚刚在您检查大小并发现它是空的之后添加了一个新客户端,而您打算将其丢弃。就让空集留在那里,这没什么坏处。