hjr-java源碼: SimpleDateFormat

分類

三種操作時間的方法都不是線程安全的

  1. SimpleDateFormat類主要用於轉換格式,String←→Date;

  2. Date類用於獲取毫秒數,或者設置Calendar對象的參數,date.getTime()、calendar.setTime(date)

  3. Calendar類用於具體操作,比如獲取指定年、月的天數,加一年一月等。

線程安全

SimpleDateFormat 爲什麼是線程不安全的?

SimpleDateFormat類實現了 sdf.parse(dateStr), sdf.format(date)等時間轉化的方法,該類內部維護一個Calendar 全局變量

風險就出在Calendar 全局變量上,不同線程訪問該變量會造成線程安全問題

如果sdf是個static的,那麼多線程之間會共享sdf, 即共享這個Calendar引用,sdf.parse() 方法有如下的調用:

Date parse() {
  calendar.clear(); // 清理calendar
  ... // 執行一些操作, 設置 calendar 的日期什麼的
  calendar.getTime(); // 獲取calendar的時間
}
  1. 如果 線程A 調用了 sdf.parse(), 並且進行了 calendar.clear()後還未執行calendar.getTime(),線程B又調用了sdf.parse(), 這時候線程B也執行了sdf.clear()方法,這樣就導致線程A的的calendar數據被清空了(實際上A,B的同時被清空了).

  2. 或者當 A 執行了calendar.clear() 後被掛起,這時候B 開始調用sdf.parse()並順利i結束,這樣 A 的 calendar內存儲的的date,變成了後來B設置的calendar的date

解決辦法

  • 可以使用局部變量
  • 可以通過ThreadLocal包裹SimpleDateFormat全局變量(會爲每個線程創建一個副本,以空間換時間)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章