生活不是一天两天,还是要积累的,原来很多笔记都堆在了云笔记上自己看,也许分享可以让人成长更快吧,
作为技术人有时候挺蕉绿的,因为很多时候想看看其他类型的书,但是总无法静下心来,就好像不看技术书籍,不学习技术就哪里不对劲,真是一个糟糕的心态,如果你们也有类似问题,让我们一起改变一下吧,看书确实让人愉悦,放平心态,不要管年龄,技术深浅,每天每周花些时间看其他类型的书,对于人生本身来说不仅有益,也是享受
言归正传~
TreeMap和ConcurrentSkipListMap很多特性比较像
TreeMap
看下源码的依赖关系,可以看到是实现了SortedMap,有序

来看特性,数数家珍
- 红黑树原理(有时间专门写一篇,这里不详细说)
- key有序
- key不允许重复,值可以重复
- 可排序性:可通过Comparator改变排序规则
- 线程不安全
- 支持范围查询
- 内存效率比
ConcurrentSkipListMap高,因为没有额外层次
怎么用?
(这里主要说的是和ConcurrentSkipListMap的考虑)
单线程环境下性能不错,高并发环境下性能会有一定影响,可以使用ConcurrentSkipListMap;所以使用建议非多线程环境下尽量使用TreeMap也可以提供较好的效率;对于高并发程序,可使用ConcurrentSkipListMap提供更高的并发度
如何让它线程安全?
实现方式如下
Collections.synchronizedSortedMap(new TreeMap<>(Comparator.naturalOrder()))
应用场景
- 撮合系统买单卖单
- …………
好了下面说下另一个大佬
ConcurrentSkipListMap
看下源码图例,啥意思呢,用的原理是跳表形式,后面讲解

看下它的依赖位置,根依赖是Map,实现的Map为ConcurrentMap和SortedMap ,可以知道是线程安全的和有序的了

特性如数家珍
- 跳表原理,复杂度O(log(n)),比较高效
- 线程安全,利用了锁分离技术,通过使用多个锁来减少锁竞争,锁的粒度小,这样不在同一个操作的如插入和查询,多条路径下就不会相互影响
- key有序,可传递
Comparable自定义排序 - 使用非阻塞算法:CAS;乐观锁:先假设不会发生冲突,到最后阶段检查如果有冲突进行重试操作
- key不允许重复,值可以重复
- 支持范围查询,提供如
subMapheadMaptailMap方法获取 - 无内存泄漏
- 动态调整级别,可动态调整跳表级别,适应不同负载情况
原理是跳表,所以我们讲一下跳表是什么样的情况
跳表
跳表用于快速查找,它的插入和删除只需要对整个数据结构的局部进行操作即可;高并发会拥有更好的性能;
结构如下

我们总结一下它的特性
- 多个链表分层,上面是下面的子集(一层比一层多,细,包含关系)
- 所有链表的元素都是排序的
- 搜索是跳跃式的,从上面第二级开始搜索
- 空间换时间的做法(分为多级肯定是废空间,但是搜索时间大大减少)
啥时候用呢?高并发、对性能有较高要求、不需要特别关注内存使用情况的时候,就可以用它了
栗子
举个栗子怎么搜的
比如我要搜18,就是1-7-13-下一级13-17-下一级17-18找到

比如我要搜10,搜索路径为1-7-9-10,要是普通搜索得从1搜到10搜索10次,现在搜索四次就行了

典型应用场景
- 实时排行榜
ConcurrentSkipListMap<Integer, Player> leaderboard = new ConcurrentSkipListMap<>(Comparator.reverseOrder());
leaderboard.put(player.getScore(), player); // 按分数倒序
- 事件调度器
ConcurrentSkipListMap<Long, Runnable> schedule = new ConcurrentSkipListMap<>();
schedule.put(System.currentTimeMillis() + delay, task); // 按时间排序
好,那用了synchronized的TreeMap和ConcurrentSkipListMap都线程安全,哪种效果好呢?下面对比一下
线程安全机制对比**
| 特性 | ConcurrentSkipListMap | synchronizedSortedMap(TreeMap) |
|---|---|---|
| 锁粒度 | 无锁读 + 细粒度锁写(CAS/层级锁分离) | 粗粒度锁(整个Map实例锁) |
| 并发性能 | 高并发下吞吐量高(读无锁,写竞争少) | 低并发下简单,高并发下性能骤降(所有操作串行化) |
| 锁竞争 | 几乎无读锁竞争,写操作仅在特定层级竞争 | 所有操作需竞争同一把锁 |
| 实现复杂度 | 复杂(跳表 + 无锁算法) | 简单(通过synchronized包装TreeMap) |
示例场景:
10线程并发读/写:ConcurrentSkipListMap 吞吐量可能是 synchronizedSortedMap 的 5-10倍
决策树:
感恩感谢,祝财源滚滚~
跳表相关图片引用此文章:https://javaguide.cn/java/concurrent/java-concurrent-collections.html#concurrentskiplistmap
1416

被折叠的 条评论
为什么被折叠?



