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

ConcurrentHashMap(jdk1.7)put操作确定segment后,加锁失败时,自旋外还在遍历链表,什么目的,感觉毫无意义啊
privateHashEntryscanAndLockForPut(Kkey,inthash,Vvalue){
HashEntryfirst=entryForHash(this,hash);
HashEntrye=first;
HashEntrynode=null;
intretries=-1;//negativewhilelocatingnode
while(!tryLock()){
HashEntryf;//torecheckfirstbelow
if(retries<0){
if(e==null){
if(node==null)//speculativelycreatenode
node=newHashEntry(hash,key,value,null);
retries=0;
}
elseif(key.equals(e.key))
retries=0;
else
e=e.next;
}
elseif(++retries>MAX_SCAN_RETRIES){
lock();
break;
}
elseif((retries&1)==0&&
(f=entryForHash(this,hash))!=first){
e=first=f;//re-traverseifentrychanged
retries=-1;
}
}
returnnode;
}
改成这样有啥问题呢:
privateHashEntryscanAndLockForPut(Kkey,inthash,Vvalue){
HashEntrynode=newHashEntry(hash,key,value,null);
intretries=-1;//negativewhilelocatingnode
while(!tryLock()){
if(++retries>MAX_SCAN_RETRIES){
lock();
break;
}
}
returnnode;
}
冉冉说
浏览 335回答 2
2回答

婷婷同学_

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

慕娘9325324

这边有两个出口,一个是获取锁,即tryLock()返回true,另外一个是没获取到锁,重试MAX_SCAN_RETRIES后直接lock()等待获取锁。没获取锁时,重试期间,就创建node节点,这样后面就不用创建了,节省时间
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript