使用场景是多线程,大致如下:
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)那里爆空指针了。求高人解答,破我三观吧。javaandroid数据结构多线程并发

解决方案 »

  1.   

    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 视图
    可能是这个原因吧
      

  2.   

    貌似也不对,jdk的那段解释太拗口了
      

  3.   

    Iterator<Object> iterator=map.values().iterator();
    ConcurrentHashMap 中values可以为NULL!
      

  4.   

    如果是在(1)那里爆,你是不是该看看dosomething是干啥的呢。。
      

  5.   


    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 );
    }
    }
    }
      

  6.   

    public class Microphone {
    private static final Logger LOG = LoggerFactory.getLogger(Microphone.class);
    public Son son = new Son();
    class Son{
    public String sss = "33";
    }

    public static void main(String[] args) {
    ConcurrentHashMap map =  new ConcurrentHashMap();
    Microphone  c = new Microphone();
    map.put(2, c);
    Microphone o = (Microphone) map.get(2);
    o.son = null;
    Iterator<Object> iterator=map.values().iterator();
    while(iterator.hasNext()){
    Microphone d= (Microphone)iterator.next();
    System.out.println( d.son.sss );
    }
    }
    }
      

  7.   


    如果是按照你的这个流程,我的那个案例就是d直接就是null了,而不是son是null。
      

  8.   


    看来我说的不够清楚,我再写明白一点吧ConcurrentHashMap map=initMap()//假设已经初始化过的了。
    Iterator<Object> iterator=map.values().iterator();
    while(iterator.hasNext()){
    Object o=iterator.next();
    if(o!=null){
    dosomething(o);//(1)这里会爆nullpointerexception,注意是o是null,不是它里面的成员变量出现null。
    }
    }
      

  9.   

    各位看官,我的问题已经解决了。现在我可以确定的是从ConcurrentHashMap 拿出来的值是不会出现null的情况的,这个由它自身的特性确定了,put 的时候会检测的。另外在map.values().iterator() 进行迭代的时候,其他线程对 ConcurrentHashMap 的修改都是有可能体现在 iterator 的