SimpleDateFormat与线程安全
SimpleDateFormat不是線程安全的。
SimpleDateFormat(下面簡稱sdf)類內部有一個Calendar對象引用,它用來儲存和這個sdf相關的日期信息,例如sdf.parse(dateStr),sdf.format(date) 諸如此類的方法參數傳入的日期相關String, Date等等, 都是交由Calendar引用來存儲的。這樣就會導致一個問題,如果多個線程共享sdf, 也就會共享這個Calendar引用, 并且, 觀察 sdf.parse() 方法,你會發現有如下的調用:
Date parse() {calendar.clear(); //1: 清理calendar... //2: 執行一些操作, 設置 calendar 的日期什么的calendar.getTime(); //3: 獲取calendar的時間}操作1和操作3會互相影響,并且方法又不是同步方法,所以存在線程安全問題。
如果 線程A 調用了 sdf.parse(), 并且進行了 calendar.clear()后還未執行calendar.getTime()的時候,線程B又調用了sdf.parse(), 這時候線程B也執行了sdf.clear()方法, 這樣就導致線程A的的calendar數據被清空了(實際上A,B的同時被清空了).
又或者當 A 執行了calendar.clear() 后被掛起, 這時候B 開始調用sdf.parse()并順利i結束, 這樣 A 的 calendar內存儲的的date 變成了后來B設置的calendar的date
解決方案:
1:每次用到都新建一個SimpleDateFormat,做到不在線程間共享。
由于SimpleDateFormat創建耗費很大,會涉及到大量的SimpleDateFormat對象的創建與銷毀操作,所以這種方式性能較差。適合對性能要求沒那么高的場景。
2:封裝外部方法,使用同步synchronize
這種方式在高并發場景下,對性能影響較大。可能會出現線程長時間阻塞的情況。
3:使用ThreadLocal
每個線程私有SimpleDateFormat對象,既可以避免線程安全問題,也可以避免方案1的缺點。
4:使用JDK8的最新時間&日期格式化API
如果你的jdk版本>=1.8,那推薦使用java最新的時間&日期API,使用DateTimeFormatter,它是線程安全的。
總結
以上是生活随笔為你收集整理的SimpleDateFormat与线程安全的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 燕麦粥可以减肥吗
- 下一篇: far的比较级和最高级 有两种形式