ConcurrentMap的putIfAbsent与put的区别 2022-05-25 15:28 44阅读 0赞 首先putIfAbsent与put都可以往map中添加内容,但它们在添加的时候有着很大的不同,一不注意,就会采坑。putIfAbsent在添加的时候会验证hash值,如果hash值一样,则不会更新value;但put不管hash值是否一样,每次都会更新! 比如: static ConcurrentMap<Integer, BusLine> lineMap = new ConcurrentHashMap<Integer, BusLine>(); public static void main(String[] args) { BusLine bl = new BusLine(); bl.setLineName("1"); bl.setLineId(1); lineMap.putIfAbsent(bl.getLineId(), bl); System.out.println(lineMap); BusLine b21 = new BusLine(); b21.setLineId(1); b21.setLineName("21"); lineMap.putIfAbsent(b21.getLineId(), b21); System.out.println(lineMap); BusLine b3 = new BusLine(); b3.setLineId(1); b3.setLineName("3"); lineMap.put(b3.getLineId(), b3); System.out.println(lineMap); BusLine b4 = new BusLine(); b4.setLineId(1); b4.setLineName("4"); lineMap.put(b3.getLineId(), b4); System.out.println(lineMap); } 对于上面的这段代码:它的执行结果是: {1=BusLine [Hash = 1395089624, lineName=1,]} {1=BusLine [Hash = 1395089624, lineName=1,]} {1=BusLine [Hash = 1476011703, lineName=3,]} {1=BusLine [Hash = 1603195447, lineName=4,]} 可以看出,使用putIfAbsent更新BusLine 时并没有成功,但使用put时成功了!那这是什么原因了,用hash值可以看出,b1和b21的hash值是一样的,所以不会更新value值!可是明明我们new 了2个BusLine呀!那为什么hash会一样呢? 那我们打印一下这四个对象的hash值: System.out.println("bl.hashCode ="+bl.hashCode()); System.out.println("b2l.hashCode ="+b21.hashCode()); System.out.println("b3.hashCode ="+b3.hashCode()); System.out.println("b4.hashCode ="+b4.hashCode()); bl.hashCode =1395089624 b2l.hashCode =792791759 b3.hashCode =1476011703 b4.hashCode =1603195447 我们发现这hash值是不一样的呀,那为什么map中是一样的呢?原因是得看源码: putIfAbsent的源码如下: public V putIfAbsent(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject (segments, (j << SSHIFT) + SBASE)) == null) s = ensureSegment(j); return s.put(key, hash, value, true); } put的原码如下: public V put(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment s = ensureSegment(j); return s.put(key, hash, value, false); } 可以看出区别是: `s.put(key, hash, value, ` `true` `); 和s.put(key, hash, value, false)` 也就是说 onlyIfAbsent为true的情况下才会更新! `而onlyIfAbsent为true的情况就是map中存在可以的情况。` 文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。
相关 ConcurrentMap.putIfAbsent(key,value) 用法 业务上经常会遇到有这种场景,全局维护一个并发的ConcurrentMap, Map的每个Key对应一个对象,这个对象需要只创建一次。如果Map中该key对应的value不存在则 骑猪看日落/ 2021年05月12日 19:55/ 0 赞/ 291 阅读
相关 POST 和 PUT 的区别 1、GET参数通过URL传递,POST放在Request body中。 2、GET请求会被浏览器主动cache,而POST不会,除非手动设置。 3、GET请求参数会被完整保 雨点打透心脏的1/2处/ 2022年02月05日 11:41/ 0 赞/ 90 阅读
相关 深入理解ConcurrentMap.putIfAbsent(key,value) 用法 深入理解ConcurrentMap.putIfAbsent(key,value) 用法 2014年10月22日 22:26:46 [吴孟达][Link 1] 阅读数:99 深碍√TFBOYSˉ_/ 2022年02月13日 23:21/ 0 赞/ 83 阅读
相关 彻头彻尾的理解ConcurrentMap 转载:[https://blog.csdn.net/justloveyou\_/article/details/72783008][https_blog.csdn.net_ju ﹏ヽ暗。殇╰゛Y/ 2022年05月05日 20:58/ 0 赞/ 45 阅读
相关 ConcurrentMap的putIfAbsent与put的区别 首先putIfAbsent与put都可以往map中添加内容,但它们在添加的时候有着很大的不同,一不注意,就会采坑。putIfAbsent在添加的时候会验证hash值, 港控/mmm°/ 2022年05月25日 15:28/ 0 赞/ 45 阅读
相关 map的put和putIfAbsent使用 直接上源码 default V putIfAbsent(K key, V value) { V v = get(key); 矫情吗;*/ 2022年06月06日 09:17/ 0 赞/ 60 阅读
相关 GET POST PUT DELETE 含义与区别 本文转自:http://286.iteye.com/blog/1420713 1. POST /uri 创建 2. DELETE /uri/xxx 删除 3. ゝ一纸荒年。/ 2022年08月21日 18:59/ 0 赞/ 39 阅读
相关 get、put、post、delete含义与区别 原文链接:[http://www.15yan.com/story/7dz6oXiSHeq/][http_www.15yan.com_story_7dz6oXiSHeq] [ 红太狼/ 2022年09月22日 19:41/ 0 赞/ 37 阅读
相关 LinkedBlockingQueue的offer与put的区别 首先,看一下LinkedBlockingQueue的put方法的源码: / Inserts the specified element at th 向右看齐/ 2022年09月24日 09:28/ 0 赞/ 30 阅读
相关 java基础总结(八十五)--java8新特性之put与compute,computeIfAbsent与putIfAbsent区别 [原文链接][Link 1] <table> <tbody> <tr> <td> </td> <td>是否覆盖value</td> 悠悠/ 2022年11月01日 13:24/ 0 赞/ 51 阅读
还没有评论,来说两句吧...