一、多线程put后get为null 

  源码定位

 void  transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for ( int j = 0 ; j < src.length; j++) {
Entry e = src[j];
if (e != null ) {
src[j] = null ;//将table[j]设置为null,并发访问到 原table返回的就是null
do {
Entry next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null );
}
}
}

  分析:线程1将src[j] = null;即将table[j] = null;因为代码第二行定义了Entry[] src = table;即src和table是对同一对象的引用。

  这时切换到线程2,线程2此时若正在调用get(key)方法:

 public V get(Object key) {  

         if (key == null)  

             return getForNullKey();  

         int hash = hash(key.hashCode());  

         // indexFor方法取得key在table数组中的索引,table数组中的元素是一个链表结构,遍历链表,取得对应key的value  

         for (Entry e = table[indexFor(hash, table.length)]; e != null; e = e.next) {  

             Object k;  

             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  

                 return e.value;  

         }  

         return null;
}

  若get(key)中key经hash和indexFor()计算后正好落到table[j]上,则此时取到的Entry为null(第11行),直接跳出for循环,来到第21行,return null,违反了错觉。

二、多线程put的时候可能导致元素丢失

  源码定位

 void  addEntry( int  hash, K key, V value,  int  bucketIndex)
{
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);//这里线程1和线程2同时获取e,执行后必然有一个丢失
if (size++ >= threshold)
resize( 2 * table.length);
}

  问题出在第4行table[bucketIndex] = new Entry<K,V>(hash,key,value,e);如果两个线程同时都取得了e,则他们下一个元素都是e,然后赋值给table元素的时候有一个成功有一个丢失(先赋值的丢失)。

HashMap多线程put后get为null和多线程put的时候可能导致元素丢失的更多相关文章

  1. Hive concat函数连接后结果为null

    Hive concat函数连接后结果为null concat函数是用来连接字符串的 使用示例: select concat('Hello','World','Java'); 运行结果: 最近我们在做需 ...

  2. 图解集合5:不正确地使用HashMap引发死循环及元素丢失

    问题引出 前一篇文章讲解了HashMap的实现原理,讲到了HashMap不是线程安全的.那么HashMap在多线程环境下又会有什么问题呢? 几个月前,公司项目的一个模块在线上运行的时候出现了死循环,死 ...

  3. 集合(五)不正确地使用HashMap引发死循环及元素丢失

    前一篇文章讲解了HashMap的实现原理,讲到了HashMap不是线程安全的.那么HashMap在多线程环境下又会有什么问题呢? 几个月前,公司项目的一个模块在线上运行的时候出现了死循环,死循环的代码 ...

  4. [转]Java多线程干货系列—(一)Java多线程基础

    Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...

  5. iOS多线程编程指南(一)关于多线程编程(转)

    原文:http://www.dreamingwish.com/article/ios-multi-threaded-programming-a-multi-threaded-programming.h ...

  6. java 中多线程和锁的使用以及获取多线程执行结果

    多线程一:原生的写法   关键词 implements  实现  Runnable 类 run()  方法 注意点 : 创建类的实例 InterfaceController inter=new Int ...

  7. Python 多线程、多进程 (二)之 多线程、同步、通信

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  8. js null表示没有取到html中的元素 undenfind 表示没有被赋值

    js null表示没有取到html中的元素 undenfind 表示没有被赋值

  9. Response.Redirect("x.aspx);跳转后session为null的解决方法

    通常我们做登陆的时候都是登录成功后为管理员保存一些信息,一般都会写类似下面的代码 if(登录成功) { Session["xx"] = "user"; Resp ...

随机推荐

  1. android 与html交互java调js与js调java操作

    1.首先在项目下建一个assets目录(右击app->New->Folder->Assets Flolder),直接放在项目根目录下和res目录同级别(把所html,js,图片,cs ...

  2. ajax请求出现400错误

    ajax请求出现400错误,如题.百度了只有两种情况,一个参数错误,二是所谓的参数过长. 因为我传递的base64的图片参数,很长.刚开始以为是这个原因.后来发现不是,原因是参数错误.freemake ...

  3. 原生JavaScript运动功能系列(四):多物体多值链式运动

    原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现 原生JavaScript运动功能系列(二):缓冲运动 原生JavaScript运动功能系列(三):多物体多值运动 多物体多值链式 ...

  4. HDU 1036(平均速度 **)

    题意是求出跑了 n 圈每圈 m km 的个人的平均速度. 控制格式,特别注意,题意是输出 -:--:-- 的该人成绩作废,但要把他其他的成绩输进去,不能直接就 break ,输出也就只有一个 - ,而 ...

  5. [Android] Android : lambda expressions are not supported at this language level(需设置project language level)

    最近在Github上下载一个别人的开源项目 ,里面用到了Javajdk1.8的新特性:Lambda 表达式.而我用的Android studio发现不能用这个Lambda 表达式. 本地环境: And ...

  6. MongoDB 更新数组中的元素

    本文记录如何更新MongoDB Collection 中的Array 中的元素.假设Collection中一条记录格式如下: 现要删除scores 数组中,"type" 为 &qu ...

  7. 关于Unicode

    http://www.unicode.org/faq/utf_bom.html 有关UTF或编码表单的一般问题 Unicode是16位编码吗? Unicode文本可以以多种方式表示吗? 什么是UTF? ...

  8. linux上安装mysql,tomcat,jdk

    Linux 上安装 1 安装jdk 检测是否安装了jdk 运行 java –version 若有 需要将其卸载 a)         查看安装哪些jdk rmp –qa |grep java b)   ...

  9. IDAPython脚本之收集函数的调用信息

    转载:All Right 当我们要寻找软件漏洞 bug 的时候,或者做恶意代码分析的时候,首先会找一些常用的而且容易被错误使用的函数.但是有时候程序代码太多找的比较辛苦,并且费时间.所以我们可以写一个 ...

  10. sql -leetcode 178. Rank Scores

    Score 很好得到: select Score from Scores order by Score desc; 要得到rank, 可以通过比较比当前Score 大的Score 的个数得到: sel ...