简体   繁体   English

Java中的同步嵌套集合

[英]Synchronized nested collections in java

I'm trying to create a thread-safe data structure in java, along the lines of the following: 我试图按照以下方式在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);
            }
        }
    }
}

However, it appears that I need to add additional synchronization (I'm guessing something to protect accessing the Sets). 但是,看来我需要添加其他同步(我猜是为了保护对Set的访问)。 Is there a better collection to use here, or do I just have to add the appropriate synchronization to this? 是否在这里可以使用更好的集合,还是只需要为此添加适当的同步?

What makes you think you need additional synchronization? 是什么让您认为您需要其他同步? I don't see why that would be the case. 我不知道为什么会这样。 One thing I would change is that addSubscription should check if the set for the given server is absent, and add it atomically. 我要更改的一件事是addSubscription应该检查给定服务器的设置是否不存在,并自动添加它。 This way you avoid a race condition when two threads are adding a client to the same server: 这样,当两个线程将客户端添加到同一服务器时,可以避免争用情况:

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

Also, I would not remove the set from map after it becomes empty. 另外,在设置为空后,我不会从地图中删除该设置。 Otherwise there is another race condition: someone might have added a new client just after you checked the size and discovered that it was empty, and you are going to throw it out. 否则,会出现另一种竞争状况:在您检查了大小并发现它为空之后,可能有人添加了一个新客户端,然后您将其丢弃。 Just let the empty set stay there, there isn't much harm in that. 只是让空集呆在那里,那没有什么害处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM