首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用java.util.concurrent语义的Java并发支持

使用java.util.concurrent语义的Java并发支持
EN

Stack Overflow用户
提问于 2013-02-08 07:39:25
回答 2查看 148关注 0票数 2

我正在尝试以线程安全的方式支持以下数据结构的修改(deactivate()函数调用)-

代码语言:javascript
复制
 private static Map<String, Set<Integer>> dbPartitionStatus = new HashMap<String, Set<DBPartitionId>>();

 public void deactivate(DBPartitionId partition) throws Exception {
    synchronized (dbPartitionStatus) {
        Set<DBPartitionId> partitions = dbPartitionStatus.get(serviceName);
        if (partitions == null) {
            partitions = new HashSet<DBPartitionId>();
        }
        partitions.add(partition);
        dbPartitionStatus.put(serviceName, partitions);
    }
}

如果我将同步替换为ConcurrentHashMap & ConcurrentSkipListSet duo,将会出现一些竞争情况。

我想知道这里是否有更干净的方法来实现同步(使用java.util.concurrent)。

EN

回答 2

Stack Overflow用户

发布于 2013-02-08 12:27:15

在以下实现中应为无争用条件:

代码语言:javascript
复制
private final static ConcurrentMap <String, Set <DBPartitionId>> dbPartitionStatus = 
    new ConcurrentHashMap <String, Set <DBPartitionId>> ();

public void deactivate (DBPartitionId partition) {
    Set <DBPartitionId> partitions = dbPartitionStatus.get (serviceName);
    if (partitions == null)
    {
        partitions = new ConcurrentSkipListSet <DBPartitionId> ();
        Set <DBPartitionId> p = 
            dbPartitionStatus.putIfAbsent (serviceName, partitions);
        if (p != null) partitions = p;
    }
    partitions.add (partition);
}
票数 0
EN

Stack Overflow用户

发布于 2013-02-08 08:00:10

我个人看不出这种方法有什么问题:

代码语言:javascript
复制
private static ConcurrentHashMap<String, ConcurrentSkipListSet<DBPartitionId>> dbPartitionStatus = new ConcurrentHashMap<>();

public bool deactivate(DBPartitionId partition) throws Exception {
  ConcurrentSkipListSet<DBPartitionId> partitions = dbPartitionStatus.get(serviceName);
  if (partitions == null) {
    // Create a new set
    partitions = new ConcurrentSkipListSet<DBPartitionId>();
    // Attempt to add, if we add, ev will be null.
    ConcurrentSkipListSet<DBPartitionId> ev  = dbPartitionStatus.put(serviceName, partitions);
    // If non-null, someone else has added it, so now use it.
    if (ev != null)
      partitions = ev;
  }
  // will return true if added succesfully...
  return partitions.add(partition);
}

map中还有putIfAbsent()方法,它可以在“原子”操作中对map进行get/put操作,但是在这种情况下,它有额外的开销,每次都必须构造一个空集来传递。

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

https://stackoverflow.com/questions/14763229

复制
相关文章

相似问题

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