JDK的并发容器及使用场景

最近在研究JUC,看到了很多的并发容器。它们的特性和使用场景是不一样的。在这里,总结一下
1 .HashTable
2 .ConcurrentHashMap
3 .ConcurrentSkipListMap
4 .CopyOnWriteArrayList
5 .Vector
6 .ConcurrentLinkedQueue
7 .ConcurrectSkipListSet
下面我们挨个介绍
HashTable:对外暴露的所有方法,几乎都被synchronized修饰。synchronized是串行访问的,所以可想而知,HashTable的性能非常低
但是它串行的访问的方式非常适合于数据强一致性的场景,比如金融行业就需要强一致性
ConcurrentHashMap:jdk1.5提供,jdk1.8以前使用Segment分段锁实现并发访问,jdk1.8及以后,jdk使用锁升级的方式对synchronized关键字进行了优化,所以jdk1.8的HashMap重新启用synchronized搭配CAS方式重构了ConcurrentHashMap,进一步提升了性能。ConcurrentHashMap在put操作的时候加锁,但是在get以及size操作时,没有加锁。所以get操作很可能无法读到刚刚写入的的数据。另外一个ConcurrentHashMap底层采用数组加链表的方式存储元素,当链表的元素个数超过8个时,链表会转换为红黑树。并发情况下,红黑树的插入和删除操作会涉及到一个平衡的问题,涉及到节点很多,对所资源的竞争会非常大。所以,ConcurrentHashMap适用于数据量不是很大,同时对数据的一致性要求不高的场合
ConcurrentSkipListMap:jdk1.6引入。用来替代单线程的TreeMap。ConcurrentSkipListMap内部采用跳跃表的数据结构。在处理数据时,锁住的节点不多,非常适合于处理大数据量且存在大量增删改查的场景(千万级别的数据)
单线程情况下,TreeMap的性能比ConcurrentSkipListMap的性能一点也不差,所以我们在单线程情况下首选TreeMap

以上都是key-value的容器,下面我们说一下单值存储的容器
Vector。Vector在jdk1.0就提供了。所有对外的方法都使用synchronized关键字修饰,性能极差。同样适用于数据要求强一致性的场景
CopyOnWriteArryList:底层的实现机制是这样的:
当需要写数据时,将底层的数组复制一个副本。然后对副本进行写入操作,最后再将原数组的引用指向该副本。数组使用volatile关键字修饰,保证了读操作的可见性。数组的复制操作是非常耗费性能的。所以,CopyOnWriteArrayList适合于读远大于写的场景,比如:电商中的黑名单
ConcurrentLinkedQueue。传统的、无阻塞、FIFO队列。该队列基于链表实现,写数据时,通过cas操作,新增和删除操作非常快。所以适合于写多读少的场合,比如:抢购场景。。但是该队列是无界的,使用时要注意内存溢出的情况
ConcurrentSkipListSet有序集合。由名字也可以看出,它的底层数据结构和ConcurrentSkipListMap一样也是基于跳跃表设计。事实上,它的底层确实是由ConcurrentSkipListMap实现的,只不过只用到了key。它对应的单线程数据结构是TreeSet。平时没有用过这个数据结构。不过,既然是由ConcurrentSkipListMap实现的,应该也是适用于大数据量的写多读少的场合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值