Java性能优化-06-Java并发容器

文章讨论了并发环境中Java的Map和List容器的选择。HashMap在多线程下不安全,可能导致死循环和数据不准确,推荐使用线程安全的ConcurrentHashMap、Hashtable和ConcurrentSkipListMap。ConcurrentHashMap适合小数据量和部分无锁操作,而ConcurrentSkipListMap适合大数据量。对于List,ArrayList非线程安全,可选择Vector(强一致性但锁竞争严重)或CopyOnWriteArrayList(读写分离的并发策略)。

1-并发场景的Map

首先HashMap线程不安全,多线程环境下禁止使用:在JDK1.7之前,在并发场景下使用HashMap会出现死循环,从而导致CPU使用率居高不下,而扩容是导致死循环的主要原因。虽然Java在JDK1.8中修复了HashMap扩容导致的死循环问题,但在高并发场景下,依然会有数据丢失以及不准确的情况出现。

保证容器的线程安全,Java实现了HashtableConcurrentHashMap以及ConcurrentSkipListMap等Map容器。

Hashtable、ConcurrentHashMap是基于HashMap实现的,对于小数据量的存取比较有优势。

ConcurrentSkipListMap是基于TreeMap的设计原理实现的,略有不同的是前者基于跳表实现,后者基于红黑树实现,ConcurrentSkipListMap的特点是存取平均时间复杂度是O(log(n)),适用于大数据量存取的场景,最常见的是基于跳跃表实现的数据量比较大的缓存。

ConcurrentHashMap的整体性能要优于Hashtable,但在某些场景中,ConcurrentHashMap依然不能代替Hashtable。例如,在强一致的场景中ConcurrentHashMap就不适用,原因是ConcurrentHashMap中的get、size等方法没有用到锁,ConcurrentHashMap是弱一致性的,因此有可能会导致某次读无法马上获取到写入的数据。

ConcurrentHashMap容器,该容器在数据量比较大的时候,链表会转换为红黑树。红黑树在并发情况下,删除和插入过程中有个平衡的过程,会牵涉到大量节点,因此竞争锁资源的代价相对比较高。

非线程安全的Map容器中,基于红黑树实现的TreeMap在单线程中的性能表现得并不比跳跃表差。

因此就实现了在非线程安全的Map容器中,用TreeMap容器来存取大数据;在线程安全的Map容器中,用SkipListMap容器来存取大数据。

容器名称

特性

适用场景

Hashtable

强一致性

对数据有强一致性要求的场景

ConcurrentHashMap

基于数据+链表+红黑树实现,CAS+Synchronized实现原子性,部分操作(get、size)属于无锁操作,具有弱一致性

存取数据量小,查询操作频繁,且对数据没有强一致性要求的场景

ConcurrentSkipListMap

基于跳跃表实现,具有弱一致性

存取数据量大,增删改查操作频繁,且对数据没有强一致性要求的场景

2-并发场景的List

ArrayList是非线程安全容器,在并发场景下使用很可能会导致线程安全问题。可以考虑使用Java在并发编程中提供的线程安全数组,包括VectorCopyOnWriteArrayList

Vector也是基于Synchronized同步锁实现的线程安全,Synchronized关键字几乎修饰了所有对外暴露的方法,所以在读远大于写的操作场景中,Vector将会发生大量锁竞争,从而给系统带来性能开销。

CopyOnWriteArrayList是java.util.concurrent包提供的方法,它实现了读操作无锁,写操作则通过操作底层数组的新副本来实现,是一种读写分离的并发策略。

容器名称

特性

适用场景

Vector

强一致性

对数据有强一致性要求的场景

CopyOnWriteArrayList

基于复制副本用于有锁写操作,操作完成之后,Array容器重新指向新的副本容器,具有弱一致性

适用于读远远大于写的场景

ps:ConcurrentLinkedQueue:基于CAS乐观锁实现的,在并发时的性能要好于其它阻塞队列,因此很适合作为高并发场景下的排队队列。如果有大量的写操作,这个可以考虑...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值