为了账号安全,请及时绑定邮箱和手机立即绑定

急求!!!!oncurrentHashMap(jdk1.7)put操作确定segment后,加锁失败时,遍历链表的目的

急求!!!!oncurrentHashMap(jdk1.7)put操作确定segment后,加锁失败时,遍历链表的目的

慕桂英3389331 2019-09-25 15:27:43
ConcurrentHashMap(jdk1.7)put操作确定segment后,加锁失败时,自旋外还在遍历链表,什么目的,感觉毫无意义啊privateHashEntryscanAndLockForPut(Kkey,inthash,Vvalue){HashEntryfirst=entryForHash(this,hash);HashEntrye=first;HashEntrynode=null;intretries=-1;//negativewhilelocatingnodewhile(!tryLock()){HashEntryf;//torecheckfirstbelowif(retriesMAX_SCAN_RETRIES){lock();break;}elseif((retries&1)==0&&(f=entryForHash(this,hash))!=first){e=first=f;//re-traverseifentrychangedretries=-1;}}returnnode;}改成这样有啥问题呢:privateHashEntryscanAndLockForPut(Kkey,inthash,Vvalue){HashEntrynode=newHashEntry(hash,key,value,null);intretries=-1;//negativewhilelocatingnodewhile(!tryLock()){if(++retries>MAX_SCAN_RETRIES){lock();break;}}returnnode;}
查看完整描述

2 回答

?
森林海

TA贡献2011条经验 获得超2个赞

在网上找到的答案,感觉有一定合理性:此处遍历链表的原因:希望遍历的链表被CPUcache所缓存,为后续实际put过程中的链表遍历操作提升性能。怎么理解呢?put还是要再去遍历一次(即使链表在缓存中)?因为此时当前线程没有获取到Segment锁,所以不能进行put操作,但可以为put操作做一些准备工作(有可能加载到缓存,在缓存中执行遍历更快),使put的操作更快,从而减少锁竞争。这种思想在remove()方法中也有体现。
                            
查看完整回答
反对 回复 2019-09-25
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

这边有两个出口,一个是获取锁,即tryLock()返回true,另外一个是没获取到锁,重试MAX_SCAN_RETRIES后直接lock()等待获取锁。没获取锁时,重试期间,就创建node节点,这样后面就不用创建了,节省时间
                            
查看完整回答
反对 回复 2019-09-25
  • 2 回答
  • 0 关注
  • 430 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信