Java基礎七---Java併發基礎
阿新 • • 發佈:2021-09-22
本章節配合博文Java記憶體模型(JMM)&volatile一起食用最佳。
為什麼需要多執行緒?什麼是併發三要素?
Java如何解決併發問題(JMM)?
併發關鍵字: volatile、synchronized 和 final
先行發生原則(Hapens-Before規則)
執行緒安全的級別
一個類在可以被多個執行緒安全呼叫時就是執行緒安全的。
執行緒安全不是一個非真即假的命題,可以將共享資料按照安全程度的強弱順序分成以下五類: 不可變、絕對執行緒安全、相對執行緒安全、執行緒相容和執行緒對立。
- 不可變
不可變(Immutable)的物件一定是執行緒安全的,不需要再採取任何的執行緒安全保障措施。只要一個不可變的物件被正確地構建出來,永遠也不會看到它在多個執行緒之中處於不一致的狀態。
多執行緒環境下,應當儘量使物件成為不可變,來滿足執行緒安全。
不可變的型別:
- final 關鍵字修飾的基本資料型別
- String
- 列舉型別
- Number 部分子類,如 Long 和 Double 等數值包裝型別,BigInteger 和 BigDecimal 等大資料型別。但同為 Number 的原子類 AtomicInteger 和 AtomicLong 則是可變的。
-
絕對執行緒安全
不管執行時環境如何,呼叫者都不需要任何額外的同步措施。 -
相對執行緒安全
相對執行緒安全需要保證對這個物件單獨的操作是執行緒安全的,在呼叫的時候不需要做額外的保障措施。但是對於一些特定順序的連續呼叫,就可能需要在呼叫端使用額外的同步手段來保證呼叫的正確性。
在 Java 語言中,大部分的執行緒安全類都屬於這種型別,例如 Vector、HashTable、Collections 的 synchronizedCollection() 方法包裝的集合等。 -
執行緒相容
執行緒相容是指物件本身並不是執行緒安全的,但是可以通過在呼叫端正確地使用同步手段來保證物件在併發環境中可以安全地使用,我們平常說一個類不是執行緒安全的,絕大多數時候指的是這一種情況。Java API 中大部分的類都是屬於執行緒相容的,如與前面的 Vector 和 HashTable 相對應的集合類 ArrayList 和 HashMap 等。 -
執行緒對立
執行緒對立是指無論呼叫端是否採取了同步措施,都無法在多執行緒環境中併發使用的程式碼。由於 Java 語言天生就具備多執行緒特性,執行緒對立這種排斥多執行緒的程式碼是很少出現的,而且通常都是有害的,應當儘量避免。
執行緒安全的實現方式
- 互斥同步
synchronized 和 ReentrantLock - 非阻塞同步
- 無同步方案
- 棧封閉
- 執行緒本地儲存
- 可重入程式碼