6.9并发容器
并发容器中,线程安全的集合和map
ArrayList → CopyOnWriteArrayList
写操作时复制。当有新元素添加到CopyOnWriteArrayList时,从原数组上拷贝一份副本,在副本上做写操作,完成写操作后,将原来的数组指向副本。
注意:CopyOnWriteArrayList都是在加锁的情况下进行写操作,以避免多线程时出现多个副本,把数组搞乱了。
CopyOnWriteArrayList的缺点:
写操作时需要拷贝数组,占用内存,当数组数据较多时,可能出现 young GC或full GC
不能用于实时的的场景,由于copy出副本、新添加元素都需要时间,读取时的数据可能是旧的,虽然CopyOnWriteArrayList能做到最终的一致性,但没法满足实时性的要求
CopyOnWriteArrayList更适合读多写少的场景
CopyOnWriteArrayList读操作时都是在原数组上读的,不需要加锁,而写操作要加锁,避免多个线程并发修改时复制出多个副本
HashSet、TreeSet → CopyOnWriteArraySet、ConcurrentSkipListSet
CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,适合于很小的集合,只读操作大于写入操作的场景。
ConcurrentSkipListSet JDK6新增的类,很TreeSet一样,支持自然排序,可以在构造的时候自定义比较器,和其他Set一样,ConcurrentSkipListSet是基于Map集合的。对于contains()、add()、remove()方法都是线程安全的,但是对于批量操作,比如containsAll()、addAll()、removeAll()并不能保证以原子方式执行。ConcurrentSkipListSet 是能使用空元素的,即NULL
请自行编写代码验证线程安全性
HashMap、TreeMap → ConcurrentHashMap、ConcurrentSkipListMap
ConcurrentHashMap不运行空值,ConcurrentHashMap对读读操作进行了大量的优化,具有特别高的并发性。
ConcurrentSkipListMap基于SkipList这种跳表的结构实现的
ConcurrentHashMap与ConcurrentSkipListMap对比
根据实验,4个线程,1.6万数据的情况下,ConcurrentHashMap的存取速度是ConcurrentSkipListMap的4倍左右
ConcurrentSkipListMap的key是有序的
ConcurrentSkipListMap支持更高的并发,存取时间和线程数是几乎没有关系的,即数据量一定的情况下,线程数越多,越能体现出ConcurrentSkipListMap的优势
请自行编写代码验证线程安全性
Last updated
Was this helpful?