1 //成员变量calendar,多线程下共享 2 protected Calendar calendar; 3 4 private StringBuffer format(Date var1, StringBuffer var2, FieldDelegate var3) { 5 this.calendar.setTime(var1); 6 boolean var4 = this.useDateFormatSymbols(); 7 int var5 = 0; 8 9 while(var5 < this.compiledPattern.length) { 10 int var6 = this.compiledPattern[var5] >>> 8; 11 int var7 = this.compiledPattern[var5++] & 255; 12 if (var7 == 255) { 13 var7 = this.compiledPattern[var5++] << 16; 14 var7 |= this.compiledPattern[var5++]; 15 } 16 17 switch(var6) { 18 case 100: 19 var2.append((char)var7); 20 break; 21 case 101: 22 var2.append(this.compiledPattern, var5, var7); 23 var5 += var7; 24 break; 25 default: 26 this.subFormat(var6, var7, var3, var2, var4); 27 } 28 } 29 30 return var2; 31 }
解决方案:
阿里规范
【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。 正例:注意线程安全,使用DateUtils。亦推荐如下处理:
public class DateUtils {
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
public static Date parse(String formatPattern, String dateString) throws ParseException {
return threadLocal.get().parse(dateString);
}
public static String format(String formatPattern, Date date) {
return threadLocal.get().format(date);
}
}
说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。
public class DateUtils { public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static LocalDate parse(String dateString){ return LocalDate.parse(dateString, DATE_TIME_FORMATTER); } public static String format(LocalDate target) { return target.format(DATE_TIME_FORMATTER); } }