SimpleDateFormat多线程下的异常

来源:互联网 发布:网络直播的发展历程 编辑:程序博客网 时间:2024/05/22 17:47

  今天在生产上碰到一个怪异的问题,之前一直跑的很好的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,总比多次调用生成多个的好。

0 0
原创粉丝点击