落叶知秋|ConcurrentHashMap确实很复杂,这样学源码才简单( 三 )
还是和上面的一样 , HashTable就不说了 , putVal()方法被synchronized了 , 里面所有的操作都是线程安全的 , Collections.synchronizedMap()类似 。
我们来看看在ConcurrentHashMap中是怎么来保证线程安全的 , 还是找到putVal()方法:
casTabAt()
看上面的源码注释 , 当数组被安全的的初始化后 , 就开始put值进去了 , 这个地方一个是通过U.getObjectVolatile()来线程安全的判断出该数组下标对应的节点是否为null , 如果是null , 则执行casTabAt()方法去写入!
还是采用的是CAS无锁化的技术来保证写入的线程安全!
5、ConcurrentHashMap除了CAS还有其他保证线程安全的方式吗?上面两部分说的都是ConcurrentHashMap中用CAS来保证数组的初始化、下标为空的时候putVal()时候的线程安全 。
那是不是ConcurrentHashMap中是不是都是用CAS来保证线程安全的呢?
还有其他的方式吗?synchronized出现了!
也就是说初始化数组、数组下标为null时候采用的都是CAS操作来保证线程安全的 , 但是当当前下标不为空的时候 , 就采用synchronized来保证线程安全了:
那么问题来了:
- 不是说synchronized慢么?这里是怎么回事?
- 为什么不用CAS?
f = tabAt(tab, i = (n - 1) 这个方法主要分成三部分:
- 每个线程领取搬运元素的任务 , 每次协助搬运数组里的16个下标对应的元素;
- 不断的去检查每一个线程的任务是否完成 , 全部都完成了才返回;
- 每个线程去做任务搬运数据到新的数组 。
对应的三块源码为:
7、总结如果你已经看到这里了 , 我不甚感激 , 当然你也一定有所收获!
回过头提炼一下这些知识点 , 不关心里面的代码实现细节 , 其实就剩下最后一个问题:
面试官问你ConcurrentHashMap真正要考察的知识是什么?
如果还是考察你数组+链表+红黑树 , 那就问你HashMap就好了 。 问ConcurrentHashMap的本质是想带你进入并发编程的世界(坑) , 看看你对并发编程的掌握程度如何 。
如果你去看ConcurrentHashMap的源码 , 你会发现到处都是CAS、synchronized、volatile这些并发编程的相关知识 , ConcurrentHashMap就是靠这些东西来保证其线程安全的特性 。
【落叶知秋|ConcurrentHashMap确实很复杂,这样学源码才简单】因此 , 带着对ConcurrentHashMap的了解 , 开始进入并发编程的世界吧~
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 爆笑社|搞笑gif-哥们这样不好吧!不过看着确实有点远!
- 落叶知秋|跨境易税通应邀参加海关总署跨境电商研讨会
- 新鲜事儿|《浪姐》30岁蓝盈莹又被骂上热搜:这一次,确实是她不“懂事”了
- 落叶知秋|手机有这三种情况的,还是换了吧,别委屈自己
- 虎扑|已经想好踢巴萨的阵容,加图索:我确实应被罚下
- 杨易|《最强大脑》杨易夺冠实至名归,赵金昊实力全靠嘴?确实高看了
- 如今热刺俱乐部确实非常受欢迎,估计接下来穆里尼奥还会锁定新目标,然后完成签约
- 新机发布华为Mate40 Pro爆料:钢化膜曝光,确实很霸气!
- |清朝皇妃真容曝光:婉容长得确实漂亮,魏璎珞的原型堪称绝世美人
- 加图索|加图索:我确实应被罚下,已经想好踢巴萨的阵容