文章目錄
- 一、有三個線程T1,T2,T3如何保證順序執(zhí)行
- 二、AQS
- 三、CountDownLatch
- 四、CyclicBarrier
- 五、Semaphore
- 六、自旋鎖
- 七、偏向鎖
- 八、輕量級鎖
- 九、重量級鎖
- 十、Synchronized升級流程
- 十一、可重入鎖(ReentrantLock)
- 十二、synchronized和Lock區(qū)別
- 十三、樂觀鎖
- 十四、悲觀鎖
- 總結(jié)
一、有三個線程T1,T2,T3如何保證順序執(zhí)行
可以使用線程類中的join方法,在一個線程中啟動另一個線程,另外一個線程執(zhí)行完該線程繼續(xù)執(zhí)行。T3的run方法中執(zhí)行t2.join(),T2的run方法中執(zhí)行t1.join(),這樣就會按照T1,T2,T3的順序執(zhí)行了。
二、AQS
AQS是java.util.concurrent包下的工具類,全稱是AbstractQueuedSynchronizer抽象隊列同步器,AQS是多線程同步器,Lock、CountDownLatch、Semaphore都用到了AQS,從本質(zhì)上來說AQS提供了兩種鎖機制,分別是排它鎖和共享鎖。排它鎖:就是存在多線程競爭同一共享資源時,同一時刻只允許一個線程訪問該共享資源,也就是多個線程中只能有一個線程獲得鎖資源,比如Lock中的ReentrantLock重入鎖實現(xiàn)就是用到了AQS中的排它鎖功能。共享鎖:也稱為讀鎖,就是在同一時刻允許多個線程同時獲得鎖資源,比如CountDownLatch、Semaphore都是用到了AQS中共享鎖功能。
三、CountDownLatch
CountDownLatch是基于執(zhí)行時間的同步類,允許一個或多個線程等待其他線程完成操作,構(gòu)造方法接收一個int參數(shù)作為計數(shù)器,如果要等待n個點就傳入n,每次調(diào)用countDown方法時計數(shù)器減1,await方法阻塞當(dāng)前線程直到計數(shù)器變?yōu)?,由于countDown方法可用在任何地方,所以n個點既可以是n個線程,也可以是一個線程里的n個執(zhí)行步驟。
public class CountDownLatchDemo { //主線程等待子線程執(zhí)行完畢 public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); for (int i = 0; i { try { Thread.sleep(5000); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + “執(zhí)行了此任務(wù)”); countDownLatch.countDown(); }).start(); } countDownLatch.await(); System.out.println(“執(zhí)行主線程代碼”); }}public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { //子線程等主線程計數(shù)器變0一起執(zhí)行 CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 0; i { try { countDownLatch.await(); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + “執(zhí)行了此任務(wù)”); }).start(); } Thread.sleep(5000); System.out.println(“執(zhí)行主線程代碼”); countDownLatch.countDown(); }}
四、CyclicBarrier
循環(huán)屏障是基于同步到達(dá)某個點的信號量觸發(fā)機制,作 是讓 組線程到達(dá) 個屏障時被阻塞,直到最后 個線程到達(dá)屏障才會解除。構(gòu)造 法中的參數(shù)表示攔截線程數(shù)量,每個線程調(diào) await 法告訴CyclicBarrier 已到達(dá)屏障,然后被阻塞。還 持在構(gòu)造 法中傳 個 Runnable 任務(wù),當(dāng)線程到達(dá)屏障時會優(yōu)先執(zhí) 該任務(wù)。適 于多線程計算數(shù)據(jù),最后合并計算結(jié)果的應(yīng) 場景。CountDownLacth 的計數(shù)器只能 次, CyclicBarrier 的計數(shù)器可使 reset 法重置,所以CyclicBarrier 能處理更為復(fù)雜的業(yè)務(wù)場景,例如計算錯誤時可 重置計數(shù)器重新計算。
五、Semaphore
信號量 來控制同時訪問特定資源的線程數(shù)量,通過協(xié)調(diào)各個線程以保證合理使 公共資源。信號量可以 于流量控制,特別是公共資源有限的應(yīng) 場景, 如數(shù)據(jù)庫連接。Semaphore 的構(gòu)造 法參數(shù)接收 個 int 值,表示可 的許可數(shù)量即最 并發(fā)數(shù)。使 acquire 法獲得 個許可證,使 release 法歸還許可,還可以 tryAcquire 嘗試獲得許可。
六、自旋鎖
synchronized是重量級鎖,拿到鎖必須要阻塞,當(dāng)量大的時候會一直阻塞喚醒,優(yōu)化一下,不要讓其阻塞,只是告訴有這么個標(biāo)記,在synchronized的邊界做循環(huán),這就是自旋,如果做了多次循環(huán)發(fā)現(xiàn)還沒有獲得鎖,再阻塞。
七、偏向鎖
有一個線程來訪問代碼塊,沒有鎖的競爭,偏向某個線程,把偏向鎖的偏向標(biāo)記存儲為線程的線程id(主要是同一個線程反復(fù)搶占鎖的場景),只有一個線程,如果線程搶占那么就會升級成輕量級鎖,偏向鎖默認(rèn)是關(guān)閉的。
八、輕量級鎖
有線程競爭,自旋去判斷這個對象的鎖是否釋放,自旋次數(shù)(默認(rèn)根據(jù)上一次自旋次數(shù)和鎖的釋放時間來決定),會升級重量級鎖
九、重量級鎖
線程阻塞等待。
十、Synchronized升級流程
首先synchronized會嘗試使用偏向鎖的方式去競爭鎖資源,如果能夠競爭到偏向鎖,表示加鎖成功直接返回。如果競爭鎖失敗,說明當(dāng)前鎖已經(jīng)偏向了其他線程,需要將鎖升級到輕量級鎖,在輕量級鎖狀態(tài)下,競爭鎖的線程根據(jù)自適應(yīng)自旋次數(shù)去搶占鎖資源。如果在輕量級鎖狀態(tài)下還是沒有競爭到鎖,就只能升級到重量級鎖,在重量級鎖狀態(tài)下,沒有競爭到鎖的線程就會被阻塞,線程的狀態(tài)就是Blocked。
十一、可重入鎖(ReentrantLock)
在運行的某個函數(shù)或者代碼,因為搶占資源或者中斷等原因?qū)е潞瘮?shù)或者代碼的運行中斷,等待中斷程序執(zhí)行結(jié)束后,重新進(jìn)入這個函數(shù)或者代碼中運行,并且運行結(jié)果不會受到影響,那么這個函數(shù)或者代碼就是可重入的。ReentrantLock類實現(xiàn)了Lock,它擁有與synchronized相同的并發(fā)性和內(nèi)存語義。線程A在第一次搶占到鎖,在還沒有釋放之前再次得到鎖,這個時候就不需要重新?lián)屨兼i,而是增加重入次數(shù),然后鎖需要被釋放兩次才能獲得真正的釋放。ReentrantLock是一種可重入的排它鎖,主要用來解決多線程對共享資源競爭的問題特性:1)支持可重入。2)支持公平和非公平。3)提供了阻塞競爭鎖和非阻塞競爭鎖的兩種方法,分別是lock()和tryLock()。幾個非常關(guān)鍵的技術(shù):鎖的競爭,ReentrantLock通過互斥變量,使用CAS機制來實現(xiàn)的,沒有競爭到鎖的線程,使用了AbstractQueuedSynchronized這樣一個隊列同步器來存儲,底層是通過雙向鏈表來實現(xiàn)的,當(dāng)鎖被釋放之后,會從AQS隊列里的頭部喚醒下一個等待鎖的線程。公平和非公平的特性,主要體現(xiàn)在競爭鎖的時候,是否需要判斷AQS隊列存在等待中的線程。等待隊列里的鎖則是公平鎖,如果都可以競爭鎖,則是非公平鎖。鎖的重入特性,在AQS里面有一個成員變量來保存當(dāng)前獲得鎖的線程,當(dāng)同一個線程下次再來競爭鎖的時候,就不會去走鎖競爭的邏輯,而是直接增加重入次數(shù)。
十二、synchronized和Lock區(qū)別
十三、樂觀鎖
對于并發(fā)間操作產(chǎn)生的線程安全問題持樂觀狀態(tài),樂觀鎖認(rèn)為競爭不總是會發(fā)生,因此它不需要持有鎖,將比較替換這兩個動作作為一個原子操作嘗試去修改內(nèi)存中的變量,如果失敗則表示發(fā)生沖突,那么就應(yīng)該有相應(yīng)的重試邏輯。
十四、悲觀鎖
對于并發(fā)間操作產(chǎn)生的線程安全問題持悲觀狀態(tài),悲觀鎖認(rèn)為競爭總是會發(fā)生,因此每次對某資源進(jìn)行操作時,都會持有一個獨占的鎖,就像synchronized,直接上鎖操作資源。
總結(jié)
擇一良人,選一城市,三餐四季,春夏秋冬