(1)能夠使用鎖來處理併發問題。html
(2)使用JDK8 Instant 或 LocalDateTime替代。
安全
(1)能夠使用鎖來處理併發問題。多線程
(2)使用JDK8 LocalDateTime 替代。併發
(1)DateFormat中calendar是共享變量,其子類SimpleDateFormat中也是共享變量。app
DateFormat源碼:ide
public abstract class DateFormat extends Format {this
/**
* The {@link Calendar} instance used for calculating the date-time fields
* and the instant of time. This field is used for both formatting and
* parsing.
*
* <p>Subclasses should initialize this field to a {@link Calendar}
* appropriate for the {@link Locale} associated with this
* <code>DateFormat</code>.
* @serial
*/
protected Calendar calendar;spa
(2)SimpleDateFormat format方法源碼:線程
private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) { // Convert input date to time field list calendar.setTime(date); boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledPattern.length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i++] & 0xff; if (count == 255) { count = compiledPattern[i++] << 16; count |= compiledPattern[i++]; } switch (tag) { case TAG_QUOTE_ASCII_CHAR: toAppendTo.append((char)count); break; case TAG_QUOTE_CHARS: toAppendTo.append(compiledPattern, i, count); i += count; break; default: subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); break; } } return toAppendTo; }
當多個線程同時使用相同的 SimpleDateFormat 對象【如用static修飾的 SimpleDateFormat 】調用format方法時,多個線程會同時調用 calendar.setTime 方法,可能一個線程剛設置好 time 值另外的一個線程立刻把設置的 time 值給修改了致使返回的格式化時間多是錯誤的。code
(1)使用ThreadLocal處理static方法
public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } };
System.out.println(df.get().format(new Date()));
2019-12-14
(2)使用JDK8 DateTimeFormatter 替代。
參考:https://www.cnblogs.com/wupeixuan/p/11511915.html?utm_source=gold_browser_extension
《阿里巴巴Java開發手冊》