色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

為什么使用Java的SimpleDateFormat偶爾出現值不正確的情況?

林國瑞2年前14瀏覽0評論

我將從以下幾點進行說明:

1、SimpleDateFormat的使用

2、為什么SimpleDateFormat線程不安全呢?

3、怎樣解決SimpleDateFormat的線程不安全對象

4、總結

SimpleDateFormat的使用

我們通常都會寫一個日期處理工具類DateUtils,使用時直接使用這個實例來進行操作。代碼如下:

那么怎么使用呢?

DateUtils.parseString("2020-05-01 10:02:02")

上述代碼的調用,在大部分的時間里都會工作的很好,但是當你的項目并發比較高的時候,問題就出來了,比如轉化的時間不正確,比如報錯,線程掛死。我們看下下面案例:

執行輸入如下:

java.lang.NumberFormatException: multiple points錯誤,直接掛死,沒起來;

還有下面問題:我們只是解析 2020-05-01 10:02:02,下面輸出結果卻是各種各樣的結果。

為什么SimpleDateFormat線程不安全呢?

我們先按下JDK中是怎樣介紹SimpleDateFormat類的。

Date formats are not synchronized.

* It is recommended to create separate format instances for each thread.

* If multiple threads access a format concurrently, it must be synchronized

Date formats 是線程不安全的。推薦為每個線程創建單獨的format實例。如果多線程并發訪問同一個format實例,必須加同步操作。

那下面我們分析源碼來說明為什么線程不安全?

因為我們在工具類中把SimpleDateFormat定義為靜態變量,那么在多線程環境下SimpleDateFormat就會被多線程共享,B線程會讀取到A線程的時間,就會出現時間差異和其他問題。

那我們來看parse做了什么?

從上面代碼看(3)(4)(5) 操作不是原子性,當多個線程調用parse方法適合,比如A執行了(3)(4),也就是設置了cal對象,在執行代碼(5) 前線程B 執行了代碼(3) 清空了cal對象,由于多個線程使用的是一個cal對象,所以線程A執行(5) 的時候返回的是被線程B清空后的對象

怎樣解決SimpleDateFormat的線程不安全對象

(1) 每次使用時new一個SimpleDateFormat的 實例,這樣可以保證每個實例使用自己的Calendar實例,但是每次使用都需要new一個對象,并且使用后由于沒有其他引用,又需要回收,開銷會很大。

(2) 可以使用synchronized對SimpleDtaFormat實例進行同步

(3) 使用ThreadLocal,這樣每個線程只需要使用一個SimpleDateFormate實例,這相比第一種方式 節省了對象的創建銷毀開銷,并且不需要使多個線程同步。

(4) 使用JDK8中的DateTimeFormatter

上面說明此類是線程安全的。

總結

SimpleDateFormat是線程不安全的類,一般不要定義為 static 變量,如果定義為 static ,

必須加鎖,或者使用 DateUtils 工具類。

正例:注意線程安全,使用 DateUtils。亦推薦如下處理:

說明:如果是 JDK8 的應用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,

DateTimeFormatter 代替 SimpleDateFormat,官方給出的解釋:simple beautiful strong immutable thread-safe。