一、線程安全
線程安全概念:當(dāng)多個線程訪問同一個類(對象或方法)時。這個類始終都能表現(xiàn)出正確的行為,那么這個類(對象或方法)就是線程安全的。
synchronized:可以在任意對象及方法上加鎖,而加鎖的這段代碼稱為“互斥區(qū)”或“臨界區(qū)”。
二、多個線程多個鎖
多個線程,每個線程都可以拿到自己指定的鎖,分別獲得鎖之后,執(zhí)行 synchronized 方法體的內(nèi)容。
關(guān)鍵字 synchronize 取得的鎖都是對象鎖,而不是把一段代碼(方法)當(dāng)做鎖,哪個線程先執(zhí)行 synchronize 關(guān)鍵字的方法,哪個線程就持有該方法所屬對象的鎖,兩個對象,線程就是獲得兩個不同的鎖,他們互不影響。
有一種情況則是相同的鎖,即在靜態(tài)方法上加 synchronize 關(guān)鍵字,表示鎖定 .class 類,類級別的鎖(獨占.class 類)。
三、對象鎖的同步和異步
同步:synchronized同步的概念就是共享,如果不是共享的資源,就沒有必要進(jìn)行同步。
異步:asynchronized異步的概念就是獨立,相互之間不受到任何制約。
四、臟讀
在我們對同一個對象的方法加鎖的時候,需要考慮業(yè)務(wù)的整體性,即為 setValue/getValue 方法同時加鎖 synchronized 同步關(guān)鍵字,保證業(yè)務(wù)(service)的原子性,不然會出現(xiàn)業(yè)務(wù)錯誤(也從側(cè)面保證業(yè)務(wù)的一致性)。
五、synchronized 其它概念
synchronized 鎖重入:關(guān)鍵字 synchronized 擁有鎖重入的功能,也就是在使用 synchronized 時,當(dāng)一個線程得到了一個對象的鎖后,再次請求此對象時是可以再次得到該對象的鎖。出現(xiàn)異常時,鎖自動釋放。
使用 synchronized 聲明的方法在某些情況下是有弊端的,比如 A 線程調(diào)用同步的方法執(zhí)行一個很長時間的任務(wù),那么 B 線程就必須等待比較長的時間才能執(zhí)行,這樣的情況下可以使用 synchronized 代碼塊去優(yōu)化代碼執(zhí)行時間,也就是通常所說的減少鎖的粒度。
六、volatile 關(guān)鍵字的概念
volatile概念:volatile 關(guān)鍵字的主要作用是使變量在多個線程間可見?! ≡?Java 中,每一個線程都會有一塊工作內(nèi)存區(qū),其中存放著所有線程共享的主內(nèi)存中的變量值的拷貝。當(dāng)線程執(zhí)行時,他在自己的工作內(nèi)存區(qū)中操作這些變量。為了存取一個共享的變量,一個線程通常先獲取鎖定并去清除它的內(nèi)存工作區(qū),把這些共享變量從所有線程的共享內(nèi)存區(qū)中正確的裝入到他自己所在的工作內(nèi)存區(qū)中,當(dāng)線程解鎖時保證該內(nèi)存區(qū)中變量的值寫回到共享內(nèi)存中。
一個線程可以執(zhí)行的操作有使用(use)、賦值(assign)、裝載(load)、存儲(store)、鎖定(lock)、解鎖(unlock)。 而主內(nèi)存可以執(zhí)行的操作有讀(read)、寫(write)、鎖定(lock)、解鎖(unlock),每個操作都是原子的。
volatile 的作用就是強(qiáng)制線程到主內(nèi)存(共享內(nèi)存)里去讀取變量,而不去線程工作內(nèi)存區(qū)里去讀取,從而實現(xiàn)了多個線程間的變量可見。也就是滿足線程安全的可見性。
volatile 關(guān)鍵字雖然擁有多個線程之間的可見性,但是卻不具備同步性(也就是原子性),可以算上是一個輕量級的 synchronized ,性能要比 sunchronized 強(qiáng)很多,不會造成阻塞(在很多開源的架構(gòu)里,比如 netty 的底層代碼就大量使用 volatile,可見 netty 性能一定是非常不錯的。)這里需要注意:一般 volatile 用于只針對多個線程可見的變量操作,并不能代替 synchronized 的同步功能。
volatile 關(guān)鍵字只具有可見性,沒有原子性。要實現(xiàn)原子性建議使用 atomic 類的系列對象,支持原子性操作(注意 atomic 類只保證本身方法原子性,并不保證多次操作的原子性。)
七、線程之間通信
使用 wait/notify 方法實現(xiàn)線程間的通信。注意:這兩個方法都是 object 的類的方法,換句話說 Java 為所有的對象都提供了這兩個方法。- 1. wait/notify 必須配合 synchronized 關(guān)鍵字使用- 2. wait 方法釋放鎖,notify 方法 不釋放鎖