SimpleDateFormatはスレッドセーフではありません



Simpledateformat Is Not Thread Safe



スレッドの不安定さ

Exception in thread 'Thread-1' java.lang.NumberFormatException: multiple points at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1082) at java.lang.Double.parseDouble(Double.java:510) at java.text.DigitList.getDouble(DigitList.java:151) at java.text.DecimalFormat.parse(DecimalFormat.java:1302) at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589) at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311) at java.text.DateFormat.parse(DateFormat.java:335) at com.peidasoft.orm.dateformat.DateNoStaticUtil.parse(DateNoStaticUtil.java:17) at com.peidasoft.orm.dateformat.DateUtilTest$TestSimpleDateFormatThreadSafe.run(DateUtilTest.java:20)

スレッドの不安定さの理由

SimpleDateFormat inherits DateFormat, and defines an object of the Calendar class with a protected attribute in DateFormat: calendar. Just because the concept of Calendar tiredness is complicated, involving time zone and localization, etc., member variables are used in the implementation of Jdk to pass parameters, which causes errors in multi-threading.

解決

日付形式は同期されません。スレッドごとに個別のフォーマットインスタンスを作成することをお勧めします。複数のスレッドが同時にフォーマットにアクセスする場合は、外部で同期する必要があります。

import java.text.DateFormat import java.text.SimpleDateFormat import java.util.Date /** * Class description: Date tools * * @author ruipeng.lrp * @since 2017/12/7 **/ public class DateUtils { private static final String DEFAULTDATEPATTERN = 'yyyy-MM-dd HH:mm:ss:SS' private static final ThreadLocal formatter = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat(DEFAULTDATEPATTERN) } } public static String convertDate2String(final Date date) { if (null == date) { throw new IllegalArgumentException('input param is empty~') } return formatter.get().format(date) } public static int compareDateString(final String dateStr1, final String dateStr2) throws Exception { Loggers.IOTS_COMMON.error('dateStr1 is {}, dateStr2 is {}', dateStr1, dateStr2) Date d1 = formatter.get().parse(dateStr1) Date d2 = formatter.get().parse(dateStr2) return d1.compareTo(d2) } }