并发编程-12线程安全策略之常见的线程不安全类
文章目錄
- 腦圖
- 概述
- 字符串拼接子之StringBuilder、StringBuffer
- StringBuilder (線程不安全)
- StringBuffer (線程安全)
- 小結
- 時間相關的類 SimpleDateFormat、第三方庫joda-time、JDK8提供的類
- SimpleDateFormat (線程不安全的寫法)
- SimpleDateFormat (線程安全的寫法-堆棧封閉)
- joda-time (線程安全)
- JDK8的時間處理類(線程安全)
- Collections 中線程不安全的類
- ArrayList (線程不安全)
- HashSet (線程不安全)
- HashMap (線程不安全)
- 注意事項 (先檢查后執行-- 線程不安全)
- 代碼
腦圖
概述
前兩篇博客,我們說了 通過 不可變變量 和 線程封閉 這兩種方式來實現線程安全。
這里我們來介紹下很常見的線程不安全的類
所謂線程不安全的類,是指一個類的實例對象可以同時被多個線程訪問,如果不做同步或線程安全的處理,就會表現出線程不安全的行為,比如邏輯處理錯誤、拋出異常等。
字符串拼接子之StringBuilder、StringBuffer
- StringBuilder 一個可變的字符序列。它繼承于AbstractStringBuilder,實現了CharSequence接口。
- StringBuffer 也是繼承于AbstractStringBuilder的子類;
- StringBuilder和StringBuffer不同,前者是非線程安全的,后者是線程安全的。
StringBuilder (線程不安全)
運行結果
結果不等于5000,在多線程情況下,StringBuild是線程不安全的.
StringBuffer (線程安全)
運行結果
結果等于5000,在多線程情況下,StringBuffer是線程安全的.
小結
既然StringBuffer是線程安全的, 那為何JDK還要提供StringBuilder呢?
StringBuffer之所以是線程安全的原因是幾乎所有的方法都加了synchronized關鍵字,所以是線程安全的。 synchronized 同一時間只能有一個線程訪問,所以性能會相對較差。
在上篇博文 并發編程-11線程安全策略之線程封閉中,我們了解到 線程封閉可以確保線程安全,其中線程封閉的一種實現方式時堆棧封閉,說白了就是局部變量。
所以推薦在堆棧封閉等線程安全的環境下(方法中的局部變量)應該首先選用StringBuilder。
時間相關的類 SimpleDateFormat、第三方庫joda-time、JDK8提供的類
SimpleDateFormat 的實例對象在多線程共享使用的時候會拋出轉換異常,正確的使用方法應該是采用堆棧封閉,將其作為方法內的局部變量而不是全局變量,在每次調用方法的時候才去創建一個SimpleDateFormat實例對象,這樣利用堆棧封閉就不會出現并發問題。
另一種方式是使用第三方庫joda-time的DateTimeFormatter類 或者JDK8新提供的類 : 不可變類且線程安全 LocalDate 、java.time.LocalTime 和LocaldateTime 新的Date和Time類DateTimeFormatter
SimpleDateFormat (線程不安全的寫法)
執行結果:表現出了異常
SimpleDateFormat (線程安全的寫法-堆棧封閉)
沒有拋出異常
線程安全,無異常
joda-time (線程安全)
線程安全,無異常
JDK8的時間處理類(線程安全)
線程安全,無異常
Collections 中線程不安全的類
通常情況下,我們都是在方法內部作為局部變量使用這些集合類,很少會觸發線程不安全的問題。
如果在某些情況下定義成static,而且多個線程可以修改的時候就容易出現多線程不安全的問題。
ArrayList (線程不安全)
計數錯誤,線程不安全
HashSet (線程不安全)
計數錯誤,線程不安全
HashMap (線程不安全)
計數錯誤,線程不安全
注意事項 (先檢查后執行-- 線程不安全)
有一種寫法需要注意,即便是線程安全的對象,在這種寫法下也可能會出現線程不安全的行為,這種寫法就是先檢查后執行
if(condition(a)){handle(a); }在這個操作里,可能會有兩個線程同時通過if的判斷,然后去執行了處理方法,那么就會出現兩個線程同時操作一個對象,從而出現線程不安全的行為。這種寫法導致線程不安全的主要原因是因為這里分成了兩步操作,這個過程是非原子性的,所以就會出現線程不安全的問題。
代碼
https://github.com/yangshangwei/ConcurrencyMaster
總結
以上是生活随笔為你收集整理的并发编程-12线程安全策略之常见的线程不安全类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 并发编程-11线程安全策略之线程封闭
- 下一篇: 并发编程-13线程安全策略之两种类型的同