[讨论] 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自己去定. |