实施反驳

时间:2016-08-10 18:03:58

标签: java design-patterns concurrency hashmap

我想实施一种反制方法 现在的解决方案是:

HashMap<Integer, Integer> listeners = new HashMap<>();  

public void increaseListener(int id) {  
    synchronized(listeners) {  
       if(listeners.containsKey(id)) {  
          listeners.put(id, listeners.get(id) + 1);  
       }  
       else {  
          listeners.put(id, 1);  
       }  
    }  
}  

public void decreaseListener(int id) {  
   synchronized(listeners) {   
   if(listeners.containsKey(id)) {  
      return;
   } 
   listeners.put(id, listeners.get(id) - 1);  
   if(listeners.get(id) == 0) {  
     // no more listeners do something 
   }   
  }  
}    

有更好的方法吗?例如。用其他一些构造替换hashmap或者用整数代替整数有原子引用或其他方式吗?

2 个答案:

答案 0 :(得分:0)

另一种方法是使用ConcurrentHashMap来处理我们的线程安全问题。特别是,我们可以使用其原子性保证如下:

final Map<Integer, Integer> listeners = new ConcurrentHashMap<>();

void increaseListeners(final int id) {
  listeners.merge(id, 1, Integer::sum);
}

void decreaseListeners(final int id) {
  listeners.computeIfPresent(id, ($, count) -> {
    if (count == 1) {
      /* no more listeners -- do something ? */
    }
    return count - 1;
  });
}

上述实施的工作演示可用here on Ideone

答案 1 :(得分:0)

Guava提供AtomicLongMap,仅适用于这种情况:

AtomicLongMap<Integer> listeners = AtomicLongMap.create();

public void increaseListener(int id) {
    listeners.incrementAndGet(id);
}

public void decreaseListener(int id) {
    if (listeners.decrementAndGet(id) == 0) {
        // no more listeners
    }
}