JDK1.8版本中引入了DateTime API,加强了对时间的管理。
一、Date存在的缺陷
Date如果不格式化,打印出的日期可读性差,如下所示。
Tue Sep 10 09:34:04 CST 2019
所以通常会使用SimpleDateFormate来实现格式化,但是SDF最大的问题是线程不安全的。
private StringBuffer format(Date var1, StringBuffer var2, FieldDelegate var3) {
this.calendar.setTime(var1);
boolean var4 = this.useDateFormatSymbols();
int var5 = 0;
calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。
多线程并发如何保证线程安全:
- 1、避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大。对使用format和parse方法的地方进行加锁 => 线程阻塞性能差。
- 2、使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法。
- 3、Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但是这些方法都被弃用了。
二、LocalDateTime使用
JDK8带来了新的时间日期API也就是 java.time 包下面带来Local和Zone,两者的区别一个是基于你本地时间的,一个是你自己指定时区的。
而Local都有这几个类:LocalDateTime(既包含时间也包含日期),LocalDate(只关注日期,一般来说你只关注日期不需要时间的话用这个),LocalTime(只关注时间,不关注日期)。
当然了,实际上LocalDate和LocalTime也支持日期+时间的形式,因为LocalDate里面包含一个atTime来存储时间,同理LocalTime也有一个atDate属性
例如:
LocalDate localDate = LocalDate.of(2021,3,15);
localDate.atTime(LocalTime.now());
但是如果不想多设置的话可以直接使用LocalDateTime,将日期时间一起处理了。
LocalDateTime localDateTime = LocalDateTime.now();
所以说LocalDateTime取代Date是一个趋势,当然有人比较过二者的效率,结果是Date要比LocalDateTIme快一些,这也没办法毕竟线程安全可能就要多点取舍,未来的版本也许LocalDateTime也可以像Current集合那样线程又安全又快。
评论