[讨论] HashMap线程安全-值的覆盖

heavensay 2012-03-30
      在多线程中,有一个共享的HashMap实例map,会有线程间的安全问题。网上有一种是多线程put和get的操作引起cpu100%。
    除了上述这种情况外,有没有可能,有2个不同的key,{keyA,keyB},这2个key对应的value为valueA,valueB,在map中对应的Entry为entryA,entryB;假如这2个key进行hash以后索引是一样的,既都映射到map.table[i]。正常的话应该是map.table[i]=entryA,entryA.next=entryB;
    java有主内存和工作内存的区别,那么在多线程下,会不会存在以下情况
   1 当一个线程threadA,put(keyA,valueA)的时候map.table[i]在工作内存中的副本已经put进去了entryA,这时候还没有把这副本刷新回主内存中的map.table[i];
   2 第一步结束的时候,另一个线程threadB也准备put(keyB,valueB),但是他拷贝主内存的map.table[i]的副本到工作内存的时候,还是认为map.table[i]==null(i.e. threadA中的工作内存副本的map.table[i]==entryA),然后它赋值threadB副本中的map.table[i]=entryB;
   3 上述2步都完成了,他们都刷新副本的值到主内存中,其中的一个值就被覆盖了。

也就是说 map.table[i]=entryA|B,map.table[i].next=null。有无这种情况的发生。
     
RednaxelaFX 2012-03-30
1、觉得你说的情况是可能发生的。java.util.HashMap在没保护的情况下并发访问可能出现的奇怪情况很多。
2、请不要使用“主内存”“工作内存”的思维模型。这个表述方式从Java语言规范第3版(对应Java SE 5)和JVM规范第2版的一个补丁(同样对应Java SE 5)开始已经不再使用了。关于新规范,请参考这帖:http://rednaxelafx.iteye.com/blog/1081626
jayming 2012-03-31
RednaxelaFX 写道
1、觉得你说的情况是可能发生的。java.util.HashMap在没保护的情况下并发访问可能出现的奇怪情况很多。
2、请不要使用“主内存”“工作内存”的思维模型。这个表述方式从Java语言规范第3版(对应Java SE 5)和JVM规范第2版的一个补丁(同样对应Java SE 5)开始已经不再使用了。关于新规范,请参考这帖:http://rednaxelafx.iteye.com/blog/1081626

那新规范里是什么样的思维模型呢?
RednaxelaFX 2012-03-31
jayming 写道
那新规范里是什么样的思维模型呢?

表述方式变了。只用“happen-before”的这种方式去规范一些事件发生/可见的先后关系,而不是用“主内存”“工作内存”这种模糊不清的概念。
jayming 2012-03-31
RednaxelaFX 写道
jayming 写道
那新规范里是什么样的思维模型呢?

表述方式变了。只用“happen-before”的这种方式去规范一些事件发生/可见的先后关系,而不是用“主内存”“工作内存”这种模糊不清的概念。

可惜新的方法仍然不够清晰,而且provider的实现经常都有些差别,
heavensay 2012-04-01
    感觉还是主内存、工作内存形象些、方便些
xiaoyu 2012-04-01
heavensay 写道
    感觉还是主内存、工作内存形象些、方便些


如果是happend-before方式的话 抽象的层次不一样了.具体实现方法让vm自己去定.
Global site tag (gtag.js) - Google Analytics