`
onedear
  • 浏览: 67991 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

DateFormat的多线程不安全

阅读更多

转自自己的博客:http://onedear.cn/entry/dateFormat_synchronized.html

 

最近一个系统总是会出现一些异常数据。那个系统处理逻辑不复杂。这里用自己的话语大致描述下:系统在数据处理时用上了key-value缓存框架,由于 数据需要时效性,于是用系统名+时间做组合key,例如原有系统名是“system”,那加上时间的key是:system20100101 12:00:00 .时间是精确到小时的,这里调用的方法是key = "system"+ DateUtil.dateToString(DateUtil.getDayTIme(date));

这里贴下自己精简后的util类

/**
 * @author onedear
 *
 */
public final class DateUtil {
	
	private static DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	public static  String dateToString(Date date) {
		return sdf.format(date);
	}

	/**
	 * 返回天key
	 * @return 
	 */
	public static Date getDayTime(Date date) {
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	} 
	
}


但在实际跑的时候,这个组合key总会出现一点不可思议的数据:
如 system20100101 12:12:13 ,时间竟然不是精确到小时!

由于系统是多线程跑,发现问题总是要花费很多时间,在写了n多log后,发现可能是DateUtil工具类出现问题。
这个工具类是很久之前写的,一直没发现有什么问题。但问题明明就出现在这里,最终查jdk的DateFormat说明,发现dateFormat不是线程安全的:

Synchronization
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

 

那异常数据肯定是被其他线程修改了,最后改成

public static synchronized String dateToString(Date date) {
		return sdf.format(date);
}

 系统正常跑动。困扰几天的问题总算解决了!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics