使用ConcurrentHashMap出现的诡异问题

xuhuize 2013-11-05 11:13:14
使用场景是多线程,大致如下:
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)那里爆空指针了。

求高人解答,破我三观吧。。。。。。。
...全文
726 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuhuize 2013-11-14
  • 打赏
  • 举报
回复
引用 楼主 xuhuize 的回复:
使用场景是多线程,大致如下: 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)那里爆空指针了。 求高人解答,破我三观吧。。。。。。。
各位看官,我的问题已经解决了。现在我可以确定的是从ConcurrentHashMap 拿出来的值是不会出现null的情况的,这个由它自身的特性确定了,put 的时候会检测的。另外在map.values().iterator() 进行迭代的时候,其他线程对 ConcurrentHashMap 的修改都是有可能体现在 iterator 的
xuhuize 2013-11-08
  • 打赏
  • 举报
回复
引用 6 楼 commanager 的回复:
Iterator<Object> iterator=map.values().iterator(); ConcurrentHashMap 中values可以为NULL!
看来我说的不够清楚,我再写明白一点吧 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。 } }
xuhuize 2013-11-08
  • 打赏
  • 举报
回复
引用 10 楼 xietingyan 的回复:
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 );	
		}
	}	
}
如果是按照你的这个流程,我的那个案例就是d直接就是null了,而不是son是null。
xietingyan 2013-11-08
  • 打赏
  • 举报
回复
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 );	
		}
	}	
}
xietingyan 2013-11-08
  • 打赏
  • 举报
回复
引用 8 楼 xietingyan 的回复:

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 );	
		}
	}	
}
这个错了 不好意思
xietingyan 2013-11-08
  • 打赏
  • 举报
回复

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 );	
		}
	}	
}
lcf 2013-11-08
  • 打赏
  • 举报
回复
如果是在(1)那里爆,你是不是该看看dosomething是干啥的呢。。
commanager 2013-11-08
  • 打赏
  • 举报
回复
Iterator<Object> iterator=map.values().iterator(); ConcurrentHashMap 中values可以为NULL!
小绵羊 2013-11-08
  • 打赏
  • 举报
回复
貌似也不对,jdk的那段解释太拗口了
小绵羊 2013-11-08
  • 打赏
  • 举报
回复
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 视图 可能是这个原因吧
xuhuize 2013-11-06
  • 打赏
  • 举报
回复
引用 1 楼 huxiweng 的回复:
会不会是1那里里面的其他对象爆了空指针?
不是,就是o本身是null
xuhuize 2013-11-06
  • 打赏
  • 举报
回复
引用 1 楼 huxiweng 的回复:
会不会是1那里里面的其他对象爆了空指针?
不是,就是o爆异常
teemai 2013-11-05
  • 打赏
  • 举报
回复
会不会是1那里里面的其他对象爆了空指针?

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧