HashMap多线程put后get为null的原因

一、多线程put后get为null 

  源码定位

 1 void  transfer(Entry[] newTable) {
 2      Entry[] src = table;
 3      int  newCapacity = newTable.length;
 4      for  ( int  j =  0 ; j < src.length; j++) {
 5          Entry e = src[j];
 6          if  (e !=  null ) {
 7              src[j] =  null ;//将table[j]设置为null,并发访问到 原table返回的就是null
 8              do  {
 9                  Entry next = e.next;
10                  int  i = indexFor(e.hash, newCapacity);
11                  e.next = newTable[i];
12                  newTable[i] = e;
13                  e = next;
14              }  while  (e !=  null );
15          }
16      }
17 }

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

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

 1 public V get(Object key) {
 2
 3         if (key == null)
 4
 5             return getForNullKey();
 6
 7         int hash = hash(key.hashCode());
 8
 9         // indexFor方法取得key在table数组中的索引,table数组中的元素是一个链表结构,遍历链表,取得对应key的value
10
11         for (Entry e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
12
13             Object k;
14
15             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
16
17                 return e.value;
18
19         }
20
21         return null;
22 }

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

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

  源码定位

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

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

原文地址:https://www.cnblogs.com/codingmengmeng/p/9948749.html

时间: 2024-10-22 10:31:20

HashMap多线程put后get为null的原因的相关文章

Java - HashMap 多线程安全解析

HashMap多线程并发问题分析 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU,查看堆栈,你会发现程序都Hang在了HashMap.get()这个方法上了,重启程序后问题消失.但是过段时间又会来.而且,这个问题在测试环境里可能很难重现. 我们简单的看一下我们自己的代码,我们就知道HashMa

HashMap多线程并发问题分析

原文出处: 陶邦仁 并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU,查看堆栈,你会发现程序都Hang在了HashMap.get()这个方法上了,重启程序后问题消失.但是过段时间又会来.而且,这个问题在测试环境里可能很难重现. 我们简单的看一下我们自己的代码,我们就知道HashM

java--HashMap多线程并发问题分析

并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU,查看堆栈,你会发现程序都Hang在了HashMap.get()这个方法上了,重启程序后问题消失.但是过段时间又会来.而且,这个问题在测试环境里可能很难重现. 我们简单的看一下我们自己的代码,我们就知道HashMap被多个线程操作.

Android开发:getViewById返回null的原因定位

最近在研究开发一些基于Android的App,遇到了一些问题,其中一个比较关键的是在Activity中的onCreate()方法中获取Button对象,代码大概如下: private Button mTrueButton; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); mTr

[asp.net]ashx中session存入,aspx为null的原因(使用flash uploader)

I am using uploadify to upload files, they automatically post to the handler. I then modify the session in the handler that I have setup as a static property in a common class of the website. I then try to access that same session in the aspx page, a

HashMap多线程死循环问题

正如上篇文中所说,HashMap不是线程安全的,在被多线程共享操作时,会有问题,具体什么问题呢,一直没有个清晰的理解,今天写了个测试程序调了一下,才明白其中道理. 主要是多线程同时put时,如果同时触发了rehash操作,会导致HashMap中的链表中出现循环节点,进而使得后面get的时候,会死循环.[关于什么是rehash,读者可以自行去google了] 本文主要参考了:http://coolshell.cn/articles/9606.html,测试数据也一样. 测试代码: import j

多线程下QAxObject指针为NULL的解决办法

项目中需要对Excel进行操作,把数据中的数据写入到Excel文件中.在数据量大的情况下,操作Excel是一件费时的操作. 但是执行到下列代码时就会出现空指针的情况: 1 QAxObject *excel = new QAxObject("Excel.Application"); 2 excel->setProperty("Visible", false); 3 4 QAxObject *workbooks = excel->querySubObject

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

通常我们做登陆的时候都是登录成功后为管理员保存一些信息,一般都会写类似下面的代码 if(登录成功) { Session["xx"] = "user"; Response.Redirect("Framework.aspx"); } 当我们登录后再从其它页面访问Session["xx"]的时候发现报错说为null.郁闷具体是为什么我也不清楚. 网上百度一下有人做了如下解释,不知道是否合理 原因:当asp.net 执行 respon

ajax接收返回二维数组的json数据后显示为null

前端ajax如下: > $.ajax({url:'http://xxxx.com/action.php',//路径type:'post',data:{id:0}dataType:'json',success:function(data){console.log(data);}action.php如下:<?phpinclude "con_db.php";//连接数据库$id = $_POST['id']:$sql="select * from note where