日期:2014-05-20  浏览次数:20823 次

使用ConcurrentHashMap出现的诡异问题
使用场景是多线程,大致如下:
ConcurrentHashMap map=initMap()//假设已经初始化过的了。
Iterator<Object> iterator=map.values().iterator();
while(iterator.hasNext()){
Object o=iterator.next();
dosomething(o);//(1)这里会爆nullpointerexception
}
其他线程会对该map(同一个)进行 操作,add,remove之类的。

按照我的理解:
1.ConcurrentHashMap是不允许有null的值,不论是key还是value
2.ConcurrentHashMap.values().iterator(),是视图迭代器,官方文档里面说明其他线程对map的修改都不会影响到iterator的迭代的。也就是即使外部线程修改了map,此时此刻该线程的iterator都是正常的
基于以上2点,map.values().iterator().next()是不会出现null值的,即o是不可能出现null值的。
但是确实是在(1)那里爆空指针了。

求高人解答,破我三观吧。。。。。。。
java android 数据结构 多线程并发

------解决方案--------------------
values
public Collection<V> values()返回此映射中包含的值的 Collection 视图。该 collection 受映射支持,所以对映射的改变可在该 collection 中反映出来,反之亦然。该 collection 支持元素的移除,它通过 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 操作,从此映射中移除相应的映射关系。它不支持 add 或 addAll 操作。 
该视图的 iterator 是一个“弱一致”迭代器,它不会抛出 ConcurrentModificationException,并且确保可遍历迭代器构造时存在的元素,此外还可能(但并不保证)反映构造后的所有修改。 


指定者:
接口 Map<K,V> 中的 values
覆盖:
类 AbstractMap<K,V> 中的 values
返回:
此映射中包含的值的 collection 视图


可能是这个原因吧
------解决方案--------------------
Iterator<Object> iterator=map.values().iterator();
ConcurrentHashMap 中values可以为NULL!
------解决方案--------------------
如果是在(1)那里爆,你是不是该看看dosomething是干啥的呢。。
------解决方案--------------------

public class Microphone {
private static final Logger LOG = LoggerFactory.getLogger(Microphone.class);
public String s = "111";
public static void main(String[] args) {
ConcurrentHashMap map =  new ConcurrentHashMap();
Microphone  c = new Microphone();
map.put(2, c);
c = null;
Iterator<Object> iterator=map.values().iterator();
while(iterator.hasNext()){
Object o=iterator.next();
System.out.println( c.s );
}
}
}