您的位置:首页 > 其它

SimpleDateFormat多线程下的异常

2016-10-19 18:04 375 查看
  今天在生产上碰到一个怪异的问题,之前一直跑的很好的xml转object程序,在日期转化的过程中报错的,经过排查原因,原来是由于SimpleDateFormat在多线程下运行造成的结果。

demo例子如下:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*日期格式化
**/
public class DateFormat {
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");

public Date parseDate(String str ){
if(str == null)
return null;
try {
return SDF.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}

}

public class Test {

public static void main(String[] args) {
for(int i=0;i<10;i++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
DateFormat sdf = new DateFormat();
System.out.println(sdf.parseDate("2016-10-19"));
}
});
thread.start();
}
}
}


运行错误信息:

Exception in thread "Thread-4" Exception in thread "Thread-3" java.lang.NumberFormatException: For input string: "..10011001EE22"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:430)
at java.lang.Long.parseLong(Long.java:483)
at java.text.DigitList.getLong(DigitList.java:194)
at java.text.DecimalFormat.parse(DecimalFormat.java:1316)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1793)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
at java.text.DateFormat.parse(DateFormat.java:355)
at com.busap.DateFormat.parseDate(DateFormat.java:14)
at com.busap.Abc$1.run(Abc.java:19)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-2" java.lang.NumberFormatException: multiple points
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1110)
at java.lang.Double.parseDouble(Double.java:540)
at java.text.DigitList.getDouble(DigitList.java:168)
at java.text.DecimalFormat.parse(DecimalFormat.java:1321)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1793)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
at java.text.DateFormat.parse(DateFormat.java:355)
at com.busap.DateFormat.parseDate(DateFormat.java:14)
at com.busap.Abc$1.run(Abc.java:19)
at java.lang.Thread.run(Thread.java:745)
java.lang.NumberFormatException: multiple points
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1110)
at java.lang.Double.parseDouble(Double.java:540)
at java.text.DigitList.getDouble(DigitList.java:168)
at java.text.DecimalFormat.parse(DecimalFormat.java:1321)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1793)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
at java.text.DateFormat.parse(DateFormat.java:355)
at com.busap.DateFormat.parseDate(DateFormat.java:14)
at com.busap.Abc$1.run(Abc.java:19)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-3" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:453)
at java.lang.Long.parseLong(Long.java:483)
at java.text.DigitList.getLong(DigitList.java:194)
at java.text.DecimalFormat.parse(DecimalFormat.java:1316)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1793)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
at java.text.DateFormat.parse(DateFormat.java:355)
at com.busap.DateFormat.parseDate(DateFormat.java:14)
at com.busap.Abc$1.run(Abc.java:13)
at java.lang.Thread.run(Thread.java:745)


各种异常接踵而至,原因就是SimpleDateFormat不是线程安全类。要想解决上述问题,去掉static final 修饰符,这样每个线程生成一个SimpleDateFormat,线程之间互不影响就解决了上面的问题。不过如果在大并发的情况,就会生成一堆SimpleDateFormat类(static final 修饰符原意也是为了解决这个问题),为了优化大并发的情况,可以使用ThreadLocal。在同一个线程内共享一个SimpleDateFormat,总比多次调用生成多个的好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 SimpleDate