[JAVA学习笔记-86]ConcurrentHashMap与synchronizedMap的对比

来源:互联网 发布:linux shell 引号 参数 编辑:程序博客网 时间:2024/06/01 07:49


╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║   Property    ║     HashMap       ║    Hashtable      ║  ConcurrentHashMap  ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ 
║      Null     ║     allowed       ║              not allowed                ║
║  values/keys  ║                   ║                                         ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║Is thread-safe ║       no          ║                  yes                    ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║     Lock      ║       not         ║ locks the whole   ║ locks the portion   ║        
║  mechanism    ║    applicable     ║       map         ║                     ║ 
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║   Iterator    ║               fail-fast               ║       fail-safe     ║ 
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝


Iterator 的区别?
ConcurrentHashMap 如何实现 locks the portion
结合 synchronizedMap 的实现,对比各自的差异


1、Disadvantages of Hashtable
Hashtable为什么会被Collections.synchronizedMap取代?根据stackoverflow的大神们的讨论,小结如下:1、Hashtable已经是JAVA的
上古神迹(It is considered a relic from the deep java past--by Marko Topolnik),HashMap的一些特性,Hashtable不具备,如减少hash
冲突的算法(reduce hash collisions);2、在使用的灵活性上(性能上)较差,因为Hashtable需要同步整个Map,在高并发/并行场景下,吞吐量
上不去,HashMap提供了在不需要同步而需要使用Hash的场景下,提升吞吐量的途径,同时Collections.synchronizedMap提供了一个Wrapper来
对HashMap进行同步操作,如果需要在并行场景下有更高的吞吐量,可以考虑使用concurrent包的ConcurrentHashMap。


2、synchronizedMap 与 ConcurrentHashMap 的对比
synchronizedMap 保证数据的一致性(data consistency),在并发/并行写Map的场景下,吞吐量比Concurrent要低(因为mutex);
Concurrent因为是局部锁,最大限度避免了并发/并行写的场景下的线程同步开销,但对于读数据的场景,无法保证数据的一致性(可以
理解为读操作未必能读到最新的数据);
ConcurrentHashMap不允许null的键值对;

The ConcurrentHashMap uses very sophisticated techniques to reduce the need for synchronization and allow parallel read access by multiple threads without synchronization and, more importantly, provides an Iterator that requires no synchronization and even allows the Map to be modified during interation (though it makes no guarantees whether or not elements that were inserted during iteration will be returned). -- Michael Borgwardt


3、ConcurrentHashMap
<<伸缩性的考虑>>
所谓程序的可伸缩性,值一个应用程序,它的工作负荷增加以及使用的资源增加时,其吞吐量(处理能力)的表现。线程独占式的同步,
虽然保证了一定条件下的数据一致性,但是在高并发/并行场景下,独占会导致性能瓶颈。尽可能减少锁同步,是concurrent类型的主要特点。
ConcurrentHashMap每次update操作只对一个segment加锁,即,减小锁的粒度,以此提高吞吐量。
在网上找到一个例子,cache的实现:
提高HashMap的并发性同时还提供线程安全性的一种方法是废除对整个表使用一个锁的方式,而采用对hash表的每个bucket都使用一个
锁的方式(或者,更常见的是,使用一个锁池,每个锁负责保护几个bucket)。这意味着多个线程可以同时地访问一个Map的不同部分,而
不必争用单个的集合范围的锁。这种方法能够直接提高插入、检索以及移除操作的可伸缩性。不幸的是,这种并发性是以一定的代价换来的
——这使得对整个 集合进行操作的一些方法(例如 size() 或isEmpty())的实现更加困难,因为这些方法要求一次获得许多的锁,并且还存在
返回不正确的结果的风险。然而,对于某些情况,例如实现cache,这样做是一个很好的折衷——因为检索和插入操作比较频繁,而 size() 和 isEmpty()操作则少得多。

<<并发性>>
ConcurrentHashMap 对update operations(插入/删除)有较好的伸缩性;
对于检索操作(读),可并发/并行,并可在有线程在修改集合时进行检索,不抛出异常,但是无法保证数据的一致性。
对比来看,CopyOnWriteArrayList 可允许并发/并行的读,同样也不保证数据一致性,但可提高检索的吞吐量,同时因为进行update操作
需要大量的拷贝,此集合类型不适合密集地更新的场景。
这篇文章对其性能优化有比较好的见解,需要对其有更多认识后才能领会:
https://ria101.wordpress.com/2011/12/12/concurrenthashmap-avoid-a-common-misuse/




















阅读全文
0 0
原创粉丝点击