Java常用工具類總結(jié)
一、線程協(xié)作、控制并發(fā)流程的工具類
什么是控制并發(fā)流程?
控制并發(fā)流程的工具類,作用就是幫助我們程序員更容易得讓線程之間合作讓線程之間相互配合,來(lái)滿足業(yè)務(wù)邏輯比如讓線程A等待線程B執(zhí)行完畢后再執(zhí)行等合作策略
二、CountDownLatch倒計(jì)時(shí)門閂
倒數(shù)門:
例子:購(gòu)物拼團(tuán);大巴,人滿才會(huì)發(fā)車
流程:倒數(shù)結(jié)束之前,一直處于等待狀態(tài),直到倒計(jì)時(shí)結(jié)束,此線程才繼續(xù)工作。
開始 -> 進(jìn)入等待 -> 倒數(shù)結(jié)束 -> 繼續(xù)工作
類的主要方法介紹:
CountDownLatch(int count):僅有一個(gè)構(gòu)造函數(shù),參數(shù)count為需要倒數(shù)的數(shù)值
await():調(diào)用await()方法的線程會(huì)被掛起,他會(huì)等待直到count值為0才繼續(xù)執(zhí)行。
countDown():將count值減1,直到為0時(shí),等待的線程才會(huì)被喚起。
圖解await和countDown方法:
構(gòu)造方式代碼:
注意點(diǎn):
擴(kuò)展用法:多個(gè)線程等多個(gè)線程執(zhí)行完成后,再同時(shí)執(zhí)行
CountDownLatch是不能夠重用的,如果需要重新計(jì)數(shù),可以考慮使用CyclicBarrier或者創(chuàng)建新的CountDownLatch實(shí)例
三、Semaphore信號(hào)量
Semaphore可以用來(lái)限制或管理數(shù)量有限的資源的使用情況信號(hào)量的作用是維護(hù)一個(gè)許可證的計(jì)數(shù),線程可以獲取許可證,那信號(hào)量剩余的許可證就加一,當(dāng)信號(hào)量所擁有的許可證數(shù)量為0,name下一個(gè)還想要獲取許可證的線程,就需要等待,知道另外別的線程釋放了許可證
信號(hào)量用法:
初始化Semaphore并指定許可證數(shù)量
在需要被線程在的代碼前加acquire()或者acquireUninterruptibly()方法
在任務(wù)執(zhí)行結(jié)束后,調(diào)用release()來(lái)釋放許可證
信號(hào)量主要方法介紹:
- acquire():獲取許可證,可以中斷
- acquireUninterruptibly():獲取許可證,不能中斷
- release():歸還許可證(一定不能忘記,線程不會(huì)自動(dòng)歸還)new Semaphore(int permits, boolean fair):這里可以設(shè)置是否使用公平策略,如果傳入為true,nameSemaphore會(huì)把之前等待的線程放到FIFO的隊(duì)列里,以便于當(dāng)有了新的許可證,可以分發(fā)給之前等了最長(zhǎng)時(shí)間的線程
- tryAcquire():看看現(xiàn)在有沒(méi)有空閑的許可證,如果有就獲取,如果沒(méi)有就做別的事。
- tryAcquire(timeout):和tryAcquire一樣,但是多了一個(gè)超時(shí)時(shí)間,比如在3秒內(nèi)獲取不到許可證,就做別的事。
構(gòu)造方式代碼:
注意點(diǎn):
獲取和釋放的許可證數(shù)量必須一致否則比如每次都獲取2個(gè),但是只釋放1個(gè),隨著時(shí)間的推移,到最后許可證數(shù)量不夠用,會(huì)導(dǎo)致程序科四。
注意在初始化Semaphore的時(shí)候設(shè)置公平性,一般設(shè)置為true更合理。
并不是必須由獲取許可證的線程釋放那個(gè)許可證,事實(shí)上,獲取和釋放許可證對(duì)線程并無(wú)要求,也許是A獲取了,然后由B釋放,只要邏輯合理即可
信號(hào)量的作用,處理控制臨界區(qū)最多同時(shí)有N個(gè)線程訪問(wèn)外,另一個(gè)作用是可以實(shí)現(xiàn)“條件等待”,例如線程1需要線程2完成準(zhǔn)備工作后才能開始執(zhí)行,那么就線程1acquire,而線程2執(zhí)行之后release,這樣的話,相當(dāng)于是輕量級(jí)的CountDownLatch
四、Condition接口(又稱條件對(duì)象)
Condition作用
- 當(dāng)線程1需要等待某個(gè)條件的時(shí)候,他就去執(zhí)行condition.await()方法,一旦執(zhí)行了await()方法,線程就進(jìn)入阻塞狀態(tài)。
- 然后通常會(huì)有另外一個(gè)線程,假設(shè)是線程2,去執(zhí)行對(duì)應(yīng)的條件,知道這個(gè)條件達(dá)成的時(shí)候,線程2就會(huì)去執(zhí)行condition.signal()方法,這時(shí)JVM就會(huì)從被阻塞的線程里找到那些等待該condition的線程,當(dāng)線程1就會(huì)收到可執(zhí)行信息的時(shí)候,他的線程狀態(tài)就會(huì)變成Runnable可執(zhí)行狀態(tài)
signalAll()和signal()區(qū)別
- signalAll():會(huì)喚起所有正在等待的線程
- signal:只會(huì)喚起那個(gè)等待時(shí)間最長(zhǎng)的線程
構(gòu)造方式代碼:
注意點(diǎn):
- 實(shí)際上,如果說(shuō)lock用來(lái)代替synchronized,那么Condition就是用來(lái)代替相對(duì)應(yīng)的Object.wait/notify的,所以在用法和性質(zhì)上,幾乎都一樣
- await方法會(huì)自動(dòng)釋放持有的lock鎖,和Object.wait一樣,不需要自己手動(dòng)釋放鎖
- 調(diào)用await的時(shí)候,必須持有鎖,否則會(huì)拋出異常
CyclicBarrier循環(huán)柵欄
- CyclicBarrier循環(huán)柵欄和CountDownLatch很類似,都能阻塞一組線程
- 當(dāng)有大量線程相互配合,分別計(jì)算不同任務(wù),并且需要最后統(tǒng)一匯總的時(shí)候,我們可以使用CyclicBarrier。CyclicBarrier可以構(gòu)造一個(gè)集結(jié)點(diǎn),當(dāng)某一個(gè)線程執(zhí)行完畢,他就會(huì)到集結(jié)點(diǎn)等待,直到所有線程都到了集結(jié)點(diǎn),那么該柵欄就會(huì)被撤銷,所有線程再統(tǒng)一出發(fā),繼續(xù)執(zhí)行剩下的任務(wù)。
代碼演示:
五、CyclicBarrier和CountDownLatch的區(qū)別
- 作用不同:CyclicBarrier要等固定數(shù)量的線程都達(dá)到了柵欄位置才能繼續(xù)執(zhí)行,兒CountDownLatch只需要等待數(shù)字到0,也就是說(shuō),CountDownLatch用于時(shí)間,但是CyclicBarrier是用于線程的
- 可重用性不同:CountDownLatch在倒數(shù)到0并觸發(fā)門閂打開后,就不能再次使用了,除非新建新的實(shí)例;而CyclicBarrier可以重復(fù)使用。
到此這篇關(guān)于Java常用工具類總結(jié)的文章就介紹到這了,更多相關(guān)Java工具類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中整合Shiro實(shí)現(xiàn)權(quán)限管理的示例代碼
這篇文章主要介紹了SpringBoot中整合Shiro實(shí)現(xiàn)權(quán)限管理的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java解決浮點(diǎn)數(shù)計(jì)算不精確問(wèn)題的方法詳解
在 Java 中,浮點(diǎn)數(shù)計(jì)算不精確問(wèn)題指的是使用浮點(diǎn)數(shù)進(jìn)行運(yùn)算時(shí),由于浮點(diǎn)數(shù)的內(nèi)部表示方式和十進(jìn)制數(shù)的表示方式存在差異,導(dǎo)致計(jì)算結(jié)果可能出現(xiàn)誤差,本文就給大家介紹一下Java如何解決浮點(diǎn)數(shù)計(jì)算不精確問(wèn)題,需要的朋友可以參考下2023-09-09解決Java項(xiàng)目啟動(dòng)報(bào)錯(cuò):Logback?configuration?error?detected:問(wèn)題
這篇文章主要介紹了解決Java項(xiàng)目啟動(dòng)報(bào)錯(cuò):Logback?configuration?error?detected:問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04springboot下ueditor上傳功能的實(shí)現(xiàn)及遇到的問(wèn)題
這篇文章主要介紹了springboot下ueditor上傳功能的實(shí)現(xiàn)及遇到的問(wèn)題,本文分步驟通過(guò)實(shí)例截圖給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11springboot jdbctemplate如何實(shí)現(xiàn)多數(shù)據(jù)源
這篇文章主要介紹了springboot jdbctemplate如何實(shí)現(xiàn)多數(shù)據(jù)源問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07javabean?中使用@Transient屬性處理臨時(shí)字段
@Transient表示該屬性并非一個(gè)到數(shù)據(jù)庫(kù)表的字段的映射,ORM框架將忽略該屬性,本文給大家介紹javabean?中臨時(shí)字段的處理:@Transient,感興趣的朋友跟隨小編一起看看吧2023-08-08詳解使用spring aop實(shí)現(xiàn)業(yè)務(wù)層mysql 讀寫分離
本篇文章主要介紹了使用spring aop實(shí)現(xiàn)業(yè)務(wù)層mysql 讀寫分離,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01