日期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版本。

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