SimpleDateFormat与DateTimeFormatter线程安全问题,参考阿里巴巴Java开发手册规范处理
阿里巴巴开发手册中这样说的

不合规的代码示例:
1 2 3 4
| public class MyClass { private static SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss"); private static Calendar calendar = Calendar.getInstance(); }
|
合规的代码实例:
1 2 3 4
| public class MyClass { private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss"); private Calendar calendar = Calendar.getInstance(); }
|
在多线程环境下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class MainClass {
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String formatDate(Date date) { return sdf.format(date); }
public static Date parse(String strDate) throws ParseException { return sdf.parse(strDate); }
public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newFixedThreadPool(100); for (int i = 0; i < 20; i++) { service.execute(() -> { try { System.out.println(parse("2019-04-03 17:45:00")); } catch (ParseException e) { e.printStackTrace(); }
}); } service.shutdown(); service.awaitTermination(1, TimeUnit.DAYS);
} }
|
输出情况:部分线程获取失败

原因:把SimpleDateFormat定义为静态变量,多线程环境下SimpleDateFormat的实例就会被多个线程共享,B线程会读取到A线程的时间,就会出现时间差异和其他各种问题
SimpleDateFormat和它继承的DateFormat都不是线程安全的
解决
使用JDK1.8的DateTimeFormatter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class MainClass {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static String formatDate(LocalDateTime date) { return formatter.format(date); }
public static LocalDateTime parse(String dateNow) throws ParseException { return LocalDateTime.parse(dateNow, formatter); }
public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newFixedThreadPool(100); for (int i = 0; i < 20; i++) { service.execute(() -> { try { System.out.println(parse(formatDate(LocalDateTime.now()))); } catch (ParseException e) { e.printStackTrace(); }
}); } service.shutdown(); service.awaitTermination(1, TimeUnit.DAYS); } }
|

因此进制在多线程的情况下使用SimpleDateFormat,多线程情况应该使用DateTimeFormatter
阿里JAVA开发手册地址
手册阿里云盘链接:https://www.aliyundrive.com/s/MEtW4t5DdGh