1.ConcurrentSkipListMap 和 ConcurrentSkipListSet
-
跳跃表
参考随机算法
可以看成是TreeMap和TreeSet有序容器的并发版本
ConcurrentHashMap为什么没有使用跳跃表?而是使用复杂的红黑树?
因为Hash表的空间利用率本来就很低,如果再使用浪费空间的跳跃表,空间使用率会进一步下降。
2.ConcurrentLinkedQueue
- 可以看成LinkedList的并发版本
- 无界非阻塞队列,底层是个链表,遵循先进先出原则。
add,offer将元素插入到尾部,peek(拿头部的数据,但是不移除)和poll(拿头部的数据,但是移除)
3.写时复制容器
CopyOnWriteArrayList
CopyOnWriteArraySet写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以写时复制容器也是一种读写分离的思想,读和写不同的容器。如果读的时候有多个线程正在向容器添加数据,读还是会读到旧的数据,因为写的时候不会锁住旧的,只能保证最终一致性。
适用读多写少的并发场景,常见应用:白名单/黑名单, 商品类目的访问和更新场景。
存在内存占用问题。相对于读写锁进一步提高并发性,典型利用空间换时间。
参考
- 1)享学课堂Mark老师笔记