- SimpleDateFormat,并不是一个线程安全的类。 使用 ThreadLocal 优化
比如多线程任务执行业务逻辑中存在时间字段的格式处理,出错的概率低,这个主要是因为业务并发量问题,大多数并发小,一旦大起来,那就会导致当前线程取得时间,是其他线程设置了的时间,时间覆盖错乱,因为其底层是final修饰,共享变量且没有做线程安全控制锁之类的;为了线程安全最直接的方式,就是每次调用都直接 new SimpleDateFormat。但这样的方式终究不是最好的,所以我们使用 ThreadLocal ,来优化这段代码。
private static ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(
() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
public static void main(String[] args) {
while (true) {
new Thread(() -> {
String dateStr = threadLocal.get().format(new Date());
try {
Date parseDate = threadLocal.get().parse(dateStr);
String dateStrCheck = threadLocal.get().format(parseDate);
boolean equals = dateStr.equals(dateStrCheck);
if (!equals) {
System.out.println(equals + " " + dateStr + " " + dateStrCheck);
} else {
System.out.println(equals);
}
} catch (ParseException e) {
System.out.println(e.getMessage());
}
}).start();
}
}
如上我们把 SimpleDateFormat ,放到 ThreadLocal 中进行使用,即不需要重复
new 对象,也避免了线程不安全问题 ,使用 ThreadLocal 一定要记得 new ThreadLocal<>().remove(); 操作。
避免弱引用发生 GC 后,导致内存泄漏的问题。不过如果持续使用就不用移除
优化方式二:(Java8里的 java.time.format.DateTimeFormatter是线程安全的, time里的DateTimeFormat也是线程安全的)。
Java8日期类LocalDate、LocalTime、LocalDateTime使用详解-CSDN博客
SimpleDateFormat两个著名的坑_为什么simpledateformat.format(new date())会产生一些不正确的时间-CSDN博客