HashMap对象重复赋值在多线程中的教训

 

  分享个教训,因为这个小错误,我付出了三天时间来找原因,最后发现时,才如梦方醒:

 

  上下文:用多个线程从一个ConurrentLinkedQueue里读文件名字,解析出文件名里的日期,然后把名字和日期放到另一个ConurrentLinkedQueue里,线程是这样写的:

    

HashMap nameDateMap = new HashMap(2);
		try{
			while(true)
			{
				if(!this.isRunning)
				{
					this.wait();
					wakeup = System.currentTimeMillis();
				}
				else
				{
					logger.debug("Processing file : " + fileName );
					
					dataSetID = determineType(fileName);
					if(dataSetID.length() > 0)
					{						
						nameDateMap.put("fileName", fileName);
						nameDateMap.put("fileDate", parseTime(fileName));
						idQueueMap.get(dataSetID).add(nameDateMap);  //将文件放入该类型对应的待解码队列
					}
					
					this.setRunning(false);
				}
							}
		}catch(InterruptedException ie)
		{
			logger.debug("Determine thread is interrupted: " + ie.getMessage());
		}

  

    接收者总是提示接收到了重复的名字,但是我这里logger语句明明没看到哪个文件名被重复发送了,纠结得很。最后,聪明的同事说,HashMap对象是在while循环外面声明的(第一行代码那里),但是在循环里面这个HashMap对象反复了put了key相同的两个键值对,问题可能就出在这里。于是,把第一行语句移到else里面去,接受者再也没有提示重复了,而之前看不到重复发送的迹象,是因为打印的是文件名,而不是打印的HashMap里的值。 当然,放值前调用HashMap的clear方法比重新创建对象要好。一个教训,又上了一课。如果你想对HashMap等Java集合类对象重复使用时,千万记得在重复装载值之前调用clear方法,这条教训我记得在《设计模式之禅》里作者强调过,唉~~自己体会到了!死了多少脑细胞才记住一条教训啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值