专业的JAVA编程教程与资源

网站首页 > java教程 正文

concurrenthashmap在1.7和1.8中的区别

temp10 2024-12-11 17:11:52 java教程 9 ℃ 0 评论

上次有小伙伴在评论中说能不能说一下concurrenthashmap在1.7和1.8中的区别,这次就给大家发出来。有不对的地方还请指正。

1. 1.8相比1.7,主要改变为:

concurrenthashmap在1.7和1.8中的区别

a. 去除Segment+HashEntry+UnSafe的实现,改为Synchronized+CAS+Node+UnSafe的实现,其实Node和HashEntry的内容一样,但是HashEntry是一个内部类。用Synchronized+CAS代替Segment,这样锁的粒度更小了,并且不是每次都要加锁了,CAS尝试失败了再加锁。

b. Put()方法中初始化数组大小时。1.8不用加锁,因为用了个sizeCtl变量,将这个变量置为-1,就表明table正在初始化。

2. 下面简单介绍几个主要的方法的一些区别:

a. Put()方法

i. 1.7中的实现:

ConCurrentHashMap和HashMap的put方法实现基本类似,所以主要讲一下为了实现并发性,ConCurrentHashMap 1.7有了什么改变:

1) 需要两次定位(segment(i),segment中的table[i])

由于引入了segment的概念,所以需要

a) 先通过key的rehash值的高位和segments数组大小-1相与得到再segments中的位置

b) 然后再通过key的rehash值和table数组大小-1相与得到在table中的位置;

2) 没获取到segment锁的线程,没有权利进行put操作,不像是HashTable一样去挂起等待,而是会去做一下put操作前的准备:

a) table[i]的位置(你的值需要put到哪个桶中)

b) 通过首节点first遍历链表找有没有相同key

c) 在进行上述步骤的期间还不断自旋获取锁,超过64次线程挂起!

ii. 1.8中的实现:

1) 先拿到rehash值定位,拿到table[i]的首节点first,然后

a) 如果为nul,通过CAS的方式把value put进去

b) 如果为非null,并且first.hash == -1,说明其他线程在扩容,参与一起扩容;

c) 如果非null,并且first.hash != -1,Synchronized锁住first节点,判断是链表还是红黑树,遍历插入。

b. get()方法

i. 1.7中的实现:

1) 由于变量value是由volatile修饰的,Java内存模型中的happen before规则保证了对于volatile修饰的变量始终是写操作先于读操作的,并且还有volatile的内存可见性保证修改完的数据可以马上更新到主存中,所以能保证在并发情况下,读出来的数据是最新额数据;

2) 如果get()到的是null值才去加锁。

ii. 1.8中的实现

1) 与1.7类似

c. resize()方法

i. 1.7中的实现:

1) 和HashMap中的resize()没多大区别,都是在put元素时去做的扩容,所以在1.7中的实现是获得了锁之后,在单线程中去做扩容(1.new个2倍数组,2.遍历old数组节点搬去新数组);

ii. 1.8中的实现:

1) 1.8的扩容支持并发迁移节点,从old数组的尾部开始,如果该桶被其他线程处理过了,就创建一个ForwardingNode放到该桶的首节点,hash值为-1,其他线程判断hash值为-1后就知道该桶被处理过了。

d. 计算size

i. 1.7中的实现:

1) 先采用不加锁的方式,计算两次,如果两次结果一样,说明是正确的,返回;

2) 如果两次结果不一样,则把所有segment锁住,重新计算所有segment的count的和。

ii. 1.8中的实现:

由于没有segment的概念,所以只需要用一个baseCount变量来记录ConcurrentHashMap当前节点的个数。

1) 先尝试通过CAS修改baseCount;

2) 如果多线程竞争激烈,某些线程CAS失败,那就产生过hi将CELLSBUSY置为1,成功则可以把baseCount变化的次数暂存到一个数组counterCells中,后续数组counterCells的值会加到baseCount中;

3) 如果CELLSBUSY置1失败又会反复进行CASbaseCount和CAScounterCells数组。

想获取完整面试题及答案的同学请点赞、关注并转发。私信楼主:“Java面试题”获取完整资料,更有超全spring、jvm、linux、docker等电子书相送。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表