假设我有一个ConcurrentHashMap
客户端注册到服务器(在Server类中):
Map<ClientID, String> registeredClients = new ConcurrentHashMap<ClientID, String>();
在我的注册方法中(在Server类中),我有:
public void synchronized register(ClientID client, String clientName) {
if(!registeredClients.containsKey(client))
registeredClients.put(client, clientName);
}
在服务器的任何其他方法中,我总是在开始时检查客户端是否已注册(以确保他有资格使用该方法):
if(!registeredClients.containsKey(client))
throw new UnknownClientException();
每个客户端有一个服务器线程。
我是否需要将该支票与类似内容同步?
synchronized(registeredClients) {
if(!registeredClients.containsKey(client))
throw new UnknownClientException();
}
我认为应该这样做,因为从理论上讲,客户端可以在通过if防护之后并引发异常之前注册(使异常实际上是错误的)。
我不太了解
ConcurrentHashMap
可以帮助程序员解决同步问题。 最佳答案
不,如果Class为ConcurrentHashMap,则不必同步containsKey api,因为如documentation中所述,其操作是线程安全的(您可以阅读所有文档,以了解如何管理并发访问)。
我建议您进行两个修改:
更改Map<ClientID, String> registeredClients = new ConcurrentHashMap<ClientID, String>();
至ConcurrentMap<ClientID, String> registeredClients = new ConcurrentHashMap<ClientID, String>();
因为您要在代码中显式管理并发访问
完成1.后,您可以使用registeredClients.putifAbsent(client, clientName);
代替
if(!registeredClients.containsKey(client))
registeredClients.put(client, clientName);
并避免在方法签名中使用
synchronized
关键字关于java - Java ConcurrentHashMap和同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30776176/