溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java?SimpleDateFormat線程不安全問題怎么解決

發(fā)布時間:2023-03-25 11:18:45 來源:億速云 閱讀:98 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“Java SimpleDateFormat線程不安全問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Java SimpleDateFormat線程不安全問題怎么解決”吧!

    多線程SimpleDateFormat

    public class DateTest {
        //工具類中的日期組件
        private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    
        public static void main(String[] args) throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
            for (int i = 0; i < 100; i++) {
                threadPoolExecutor.execute(() -> {
                    String dateString = sdf.format(new Date());
                    try {
                        Date parseDate = sdf.parse(dateString);
                        String dateString2 = sdf.format(parseDate);
                        System.out.println(dateString.equals(dateString2));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    結(jié)果

    Java?SimpleDateFormat線程不安全問題怎么解決

    原因分析

    全局變量的SimpleDateFormat,在并發(fā)情況下,存在安全性問題。

    我們通過源碼看下:

    SimpleDateFormat繼承了 DateFormat

    Java?SimpleDateFormat線程不安全問題怎么解決

    DateFormat類中維護了一個全局的Calendar變量

    Java?SimpleDateFormat線程不安全問題怎么解決

    sdf.parse(dateStr)和sdf.format(date),都是由Calendar引用來儲存的。

    如果SimpleDateFormat是static全局共享的,Calendar引用也會被共享。

    又因為Calendar內(nèi)部并沒有線程安全機制,所以全局共享的SimpleDateFormat不是線性安全的。

    解決方法

    解決方法1

    「FastDateFormat(FastDateFormat能保證線程安全) 替換 SimpleDateFormat」

    private static final FastDateFormat sdf = FastDateFormat.getInstance(“yyyy-MM-dd HH:mm:ss”);

     測試代碼如下所示:

    public class DateTest {
        //工具類中的日期組件
    //    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        private static final FastDateFormat sdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
    
        public static void main(String[] args) throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
            for (int i = 0; i < 100; i++) {
                threadPoolExecutor.execute(() -> {
                    String dateString = sdf.format(new Date());
                    try {
                        Date parseDate = sdf.parse(dateString);
                        String dateString2 = sdf.format(parseDate);
                        System.out.println(dateString.equals(dateString2));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
            threadPoolExecutor.shutdown();
        }
    }

    打印結(jié)果:

    Java?SimpleDateFormat線程不安全問題怎么解決

    解決方法2

    「使用DateTimeFormatter(DateTimeFormatter是線程安全的,java 8+支持)代替SimpleDateFormat」

    private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

    測試代碼如下:

    public class DateTest {
    //工具類中的日期組件
    // private static final SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
    private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

    // private static final FastDateFormat sdf = FastDateFormat.getInstance(“yyyy-MM-dd HH:mm:ss”);

    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
        for (int i = 0; i < 100; i++) {
            threadPoolExecutor.execute(() -> {
                try {
                    String dateString = sdf.format(LocalDateTime.now());
                    TemporalAccessor temporalAccessor = sdf.parse(dateString);
                    String dateString2 = sdf.format(temporalAccessor);
                    System.out.println(dateString.equals(dateString2));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        threadPoolExecutor.shutdown();
    }

    打印結(jié)果如下:

    Java?SimpleDateFormat線程不安全問題怎么解決

    到此,相信大家對“Java SimpleDateFormat線程不安全問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI