`
goodguyzl
  • 浏览: 46032 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

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方法,这条教训我记得在《设计模式之禅》里作者强调过,唉~~自己体会到了!死了多少脑细胞才记住一条教训啊!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics