2012-01-29 66 views
4

get(Key)方法调用AA标准HashMapConcurrentHashMap等于在性能时,没有修改发生的垫层地图(因此只得到()操作?执行)Java并发:都是“获得(键)HashMap和ConcurrentHashMap的性能等于

更新与背景:

并发是一个相当KOMPLEX话题:我做NEAD“并发/ threadsafety”,但只有在放,这种情况发生非常很少而对于卖出期权,我可以交换地图关联。本身(这是原子和线程安全的)。因此,我问我正在做很多get(并且可以选择使用HashMa来实现它p(创建一个临时HashMap,将数据复制到新的HashMap和交换关联中)或使用ConcurrentHashMap ...由于我的应用程序真的有很多获取我想了解更多有关如何使用两种不同获取方式来消除性能的问题。这听起来很愚蠢,因为互联网上有很多不必要的信息,但我认为这可能会让很多人感兴趣。所以如果有人知道ConcurrentHashMap的内部工作得到它会很好回答这个问题。

非常感谢!

+2

ConcurrentHashMap是线程安全的。这伴随着每一项操作的开销。但是,除非您的应用程序花费90%的时间从中检索值,否则您不会注意到其中的差异。 – bdares 2012-01-29 03:29:59

+0

你好,为什么我会得到一个downvote?请解释为什么! – user1145216 2012-01-29 03:30:02

+0

你看看API吗?它清楚地表明写入是同步的,而检索不是。还有什么要知道的? – blackcompe 2012-01-29 06:34:51

回答

2

你可以看看源代码。 (我期待在JDK 6)HashMap.get()是非常简单的:

public V get(Object key) { 
     if (key == null) 
      return getForNullKey(); 
     int hash = hash(key.hashCode()); 
     for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
      e != null; 
      e = e.next) { 
      Object k; 
      if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
       return e.value; 
     } 
     return null; 
    } 

凡散列()做一些额外的转换和异或“改善”的哈希码。

ConcurrentHashMap.get()是更复杂一些,但不是很多

public V get(Object key) { 
    int hash = hash(key.hashCode()); 
    return segmentFor(hash).get(key, hash); 
} 

同样,散列()做一些移位和异或运算。 setMentFor(int hash)做一个简单的数组查找。唯一复杂的东西是在Segment.get()中。但即使这看起来不像火箭科学:

V get(Object key, int hash) { 
    if (count != 0) { // read-volatile 
     HashEntry<K,V> e = getFirst(hash); 
     while (e != null) { 
     if (e.hash == hash && key.equals(e.key)) { 
      V v = e.value; 
      if (v != null) 
       return v; 
      return readValueUnderLock(e); // recheck 
      } 
      e = e.next; 
     } 
} 
    return null; 
} 

获取锁的一个地方是readValueUnderLock()。评论说,这在内存模型下在技术上是合法的,但从未发生过。

总的来说,两个代码看起来都很相似。在ConcurrentHashMap中组织好一点。所以我猜测性能足够相似。

这就是说,如果真的是非常罕见的,你可以考虑实现一个“复制写入”类型的机制。

2

根据ConcurrentHashMap API,检索方法没有锁定。所以,我会说他们在表现上是平等的。

3

你在问错误的问题。

如果你需要并发性,你需要它不管的性能影响。

正常行为的程序几乎总是比快速程序排名更高。我说“几乎总是”,因为可能有商业上的理由来发布带有错误的软件,而不是直到错误得到修复才能保留下来。