2009-08-18 73 views

回答

64

同步HashMap

  1. 每种方法使用对象级锁同步。所以synchMap上的get和put方法获得一个锁。

  2. 锁定整个集合是一个性能开销。当一个线程保持锁定状态时,其他线程不能使用该集合。

ConcurrentHashMap是在JDK 5.

  1. 引入有在对象级别没有锁定,该锁定是在一个更精细的粒度。对于ConcurrentHashMap,锁可能位于散列映射存储桶级别。

  2. 较低级别锁定的效果是,您可以使同步读取器和写入器不可能用于同步集合。这导致更多的可扩展性。

  3. ConcurrentHashMap不会抛出ConcurrentModificationException如果一个线程试图修改它,而另一个线程迭代它。

这篇文章Java 7: HashMap vs ConcurrentHashMap是一个很好的阅读。强烈推荐。在SynchronizedMap

+3

那么'Hashtable'和'Synchronized HashMap'有什么区别? – roottraveller 2017-07-11 06:47:48

+0

在ConcurrentHashMap和Synchronized HashMap之间,你推荐哪一个? – Blunderchips 2017-11-25 14:16:55

76

简短的回答:

两个地图是Map接口的线程安全的实现。在期望高并发性的情况下实现更高吞吐量的ConcurrentHashMap

Brian Goetz的article关于背后的想法ConcurrentHashMap是一个非常好的阅读。强烈推荐。

+0

这是什么? HashMap的:请注意,此实现不是同步的 ,以防止意外的非同步访问地图: '地图M = Collections.synchronizedMap(新的HashMap(...));' 的http://文档。 oracle.com/javase/7/docs/api/java/util/HashMap.html – karate 2014-10-21 16:23:09

+3

“Brian Goetz的文章......是一篇很好的文章。” - 他的“Java并发实践”一书更是如此。 – 2015-07-28 14:41:37

24

ConcurrentHashMap是线程安全的,没有同步整个地图。读取可以非常快速地进行,而写入是通过锁定完成的。

5

ConcurrentHashMap使用称为lock stripping的细粒度锁定机制允许更大程度的共享访问。由于这个原因,它提供了更好的并发性可扩展性

而且迭代器返回ConcurrentHashMap弱一致,而不是失败的同步HashMap的使用快速的技术

2

方法持有对象的锁,而在ConcurrentHashMap有其中持有锁上的内容,而不是桶“锁条带化”的概念。从而提高了可扩展性和性能。

1

的ConcurrentHashMap:

1)两个地图是Map接口的线程安全的实现。

2)ConcurrentHashMap在预计高并发的情况下实现更高的吞吐量。

3)对象级别没有锁定。

同步散列映射:

1)每种方法使用对象级锁同步。

7

两者都是HashMap的同步版本,它们的核心功能和内部结构有所不同。

ConcurrentHashMap由内部分段组成,可以从概念上看作独立的HashMap。 所有这些段可以由高并发执行中的单独线程锁定。 因此,多线程可以从ConcurrentHashMap获取/放置键/值对,而不会相互阻塞/等待。 这是实现更高的吞吐量。

Collections.synchronizedMap(),我们得到的HashMap的同步版本,它是在封闭的方式进行访问。这意味着如果多个线程同时尝试访问synchronizedMap,它们将被允许以同步的方式一次一个地获取/放置键值对。

5

我们可以通过使用ConcurrentHashMap和synchronisedHashmap来实现线程安全。但是,如果你看看他们的架构,就会有很多不同。

  1. synchronisedHashmap

将维持在对象级别的锁。所以如果你想执行任何操作,比如put/get,那么你必须先获得锁。同时,其他线程不允许执行任何操作。因此,一次只有一个线程可以对此进行操作。所以等待时间会在这里增加。当你比较ConcurrentHashMap时,我们可以说性能相对较低。

  • 的ConcurrentHashMap
  • 它将保持在片段级别的锁。它有16个段,默认情况下并发级别保持为16。因此,一次有16个线程可以在ConcurrentHashMap上运行。而且,读取操作不需要锁定。所以任何数量的线程都可以对它执行get操作。

    如果thread1想要在段2中执行put操作并且thread2想要在段4上执行put操作,那么它在这里是允许的。意思是说,16个线程一次可以对ConcurrentHashMap执行更新(放入/删除)操作。

    这样等待时间就会少一些。因此,性能比同步的Hashmap要好。

    0

    的ConcurrentHashMap允许数据的并行访问。整个地图被分成几部分。

    阅读操作ie。即使在细分层面,get(Object key)也不同步。

    但写入操作即。 remove(Object key), get(Object key)在段级别获取锁定。只有整个映射的一部分被锁定,其他线程仍然可以读取除锁定之外的各个段的值。

    SynchronizedMap另一方面,在对象级别获取锁定。所有线程都应该等待当前线程,而不管操作如何(读/写)。