日期Date操作的优化

一般我们对日期的操作使用的类有Date、DateTimeFormat、Calendar,在进行日期格式操作时一般用DateTimeFormat比较多,我们知道Date出来的数据格式是

Mon Jun 15 11:00:59 CST 2020

我们想把它转换成易读的格式,使用DateTimeFormat:

public void test() {
    Date date = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    System.out.println(formatter.format(date));
}

打印结果:

2020-06-15 11:03:23

问题1:如何我们操作频繁,岂不是每次都要new一个SimpleDateFormat对象?
对于这个问题的一般解决方式是创建一个静态共享变量来避免多次创建对象:

public class Test {
    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

    ...
}

问题2:SimpleDateFormat线程安全性?
我们知道SimpleDateFormat不是线程安全的,如果涉及到多线程就要考虑这个问题了。
线程安全:有多个线程同时访问一个变量可能会出现问题,例如线程A和线程B同时访问变量s,A修改了s值,B紧接着修改了s值,然后A去拿s的值,这时候拿到的不是预期的值,这时候就出问题了;
对于这个问题一般考虑加锁:

public class Test {
    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

    public void test() {
        synchronized (formatter) {
            Date date = new Date();
            System.out.println(formatter.format(date));
        }
    }
}

问题3:对性能的影响?
如果线程很多、访问很频繁的话,一直会有线程在排队等待锁,这样的话对性能影响还是不小的,这时候可以考虑使用:
方式1:ThreadLocal

public class Test {
    private static ThreadLocal<SimpleDateFormat> formatThreadLocal = new ThreadLocal<>();

    private void dateTest() {
        SimpleDateFormat sdf = formatThreadLocal.get();
        if (sdf == null) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            formatThreadLocal.set(sdf);
        }
        System.out.println(sdf.format(new Date()));
    }
}

方式2:DateTimeFormatter代替SimpleDateFormat

private void dateTest2() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        System.out.println(formatter.format(LocalDateTime.now()));
    }
}

总结:在解决日期相关问题时,尽量用DateTimeFormatter代替SimpleDateFormat、LocalDateTime代替Calendar、Instant代替Date,注意SDK版本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章