`

SimpleDateFormat的非线程安全问题

 
阅读更多

由于SimpleDateFormat不是线程安全的,因此在多线程环境下,如果共用一个SimpleDateFormat实例,会出现线程安全问题。

例如,在解析excel里的日期字段时,会报以下异常:

java.lang.NumberFormatException: For input string: ".31023102EE22"

 

解决的办法(一):每一个线程都new 一个SimpleDateFormat对象,而不能将SimpleDateFormat放在类的静态变量里进行实例化:

	/**
	 * 格式化日期
	 * @param dateString
	 * @return
	 */
	private Date parseDate(String dateString) {
		Date date = null;
             SimpleDateFormat sdf = null;
		try {
			if(dateString.indexOf('-')>0) {
		            sdf = new SimpleDateFormat("yyyy-MM-dd");
		        } else if(dateString.indexOf('/')>0) {
		            sdf = new SimpleDateFormat("yyyy/MM/dd");
		        } else if(dateString.length()==8) {
		            sdf = new SimpleDateFormat("yyyyMMdd");
		        } 
			date = sdf.parse(dateString);
		} catch (ParseException e) {
			logger.error("Parse " + dateString + " error!", e);
		}
		return date;
	}

 

 

解决的办法(二):将SimpleDateFormat放在ThreadLocal里,然后每个线程自己获取:

 

//每一个线程
private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();
 在使用的时候,从ThreadLocal里获取,这样就能保证线程安全了。
/**
	 * 格式化日期
	 * @param dateString
	 * @return
	 */
	private Date parseDate(String dateString) {
		Date date = null;
		try {
			SimpleDateFormat sdf = threadLocal.get(); // SimpleDateFormat非线程安全
			if (sdf == null){
				if(dateString.indexOf('-')>0) {
		            sdf = new SimpleDateFormat("yyyy-MM-dd");
		        } else if(dateString.indexOf('/')>0) {
		        	sdf = new SimpleDateFormat("yyyy/MM/dd");
		        } else if(dateString.length()==8) {
		        	sdf = new SimpleDateFormat("yyyyMMdd");
		        } 
				date = sdf.parse(dateString);
			}
		} catch (ParseException e) {
			logger.error("Parse " + dateString + " error!", e);
		}
		return date;
	}
 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics