首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java ConcurrentHashMap和同步

Java ConcurrentHashMap和同步
EN

Stack Overflow用户
提问于 2015-06-11 17:00:17
回答 2查看 279关注 0票数 1

假设我有一个注册到服务器的客户端ConcurrentHashMap (在类Server中):

代码语言:javascript
复制
Map<ClientID, String> registeredClients = new ConcurrentHashMap<ClientID, String>();

在我的注册方法中(在Server类中),我有:

代码语言:javascript
复制
  public void synchronized register(ClientID client, String clientName) {
        if(!registeredClients.containsKey(client))
          registeredClients.put(client, clientName);
  }

在服务器的任何其他方法中,我总是在开始时检查客户端是否已注册(以确保他有资格使用该方法):

代码语言:javascript
复制
if(!registeredClients.containsKey(client))
  throw new UnknownClientException();

我每个客户端都有一个服务器线程。

我必须把这张支票和这样的东西同步吗?

代码语言:javascript
复制
synchronized(registeredClients) {
  if(!registeredClients.containsKey(client))
    throw new UnknownClientException();
}

我认为我应该这样做,因为从理论上讲,客户端可以在通过if防护之后和抛出异常(使异常实际上出错)之前进行注册。

我不太清楚ConcurrentHashMap对程序员解决同步问题有多大帮助。

EN

回答 2

Stack Overflow用户

发布于 2015-06-11 17:50:26

不,如果类是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);

而不是

代码语言:javascript
复制
  if(!registeredClients.containsKey(client))
          registeredClients.put(client, clientName);

并避免在方法签名中使用synchronized关键字

票数 2
EN

Stack Overflow用户

发布于 2015-06-11 17:34:50

如果您使用的是Java 8,您可以使用以下代码进行检查:

代码语言:javascript
复制
registeredClients.computeIfAbsent(client, c -> {throw new UnknownClientException();});

检查键是否存在和lambda的执行是原子的。这要求UnknownClientException是一个未检查的异常。

对于Java7,我没有这么简单的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30776176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档