JAVA多線程CountDownLatch使用詳解
前序:
上周測(cè)試給開發(fā)的同事所開發(fā)的模塊提出了一個(gè)bug,并且還是偶現(xiàn)。
經(jīng)過仔細(xì)查看代碼,發(fā)現(xiàn)是在業(yè)務(wù)中啟用了多線程,2個(gè)線程同時(shí)跑,但是新啟動(dòng)的2個(gè)線程必須保證一個(gè)完成之后另一個(gè)再繼續(xù)運(yùn)行,才能消除bug。
什么時(shí)候用?
多線程是在很多地方都會(huì)用到的,但是我們?nèi)绻胍獙?shí)現(xiàn)在某個(gè)特定的線程運(yùn)行完之后,再啟動(dòng)另外一個(gè)線程呢,這個(gè)時(shí)候CountDownLatch就可以派上用場(chǎng)了
怎么用?
先看看普通的多線程代碼:
package code; public class MyThread extends Thread { public static void main(String[] args) { MyThread th = new MyThread(); Thread t1 = new Thread(th, "Mythread"); t1.start(); System.out.println(Thread.currentThread().getName()); } public void run() { Mythread1 th2 = new Mythread1(); Thread t2 = new Thread(th2, "Mythread1"); t2.start(); System.out.println(this.currentThread().getName()); } class Mythread1 extends Thread { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(this.currentThread().getName()); } } }
代碼如上,先用MyThread繼承了Thread類,然后在MyThread類內(nèi)部又寫了一個(gè)MyThread1類,同樣也是繼承了Thread類,并且在run方法里面讓它睡1秒,這樣運(yùn)行代碼,就會(huì)打印出:
從上面的輸出順序可以看出,先是啟動(dòng)了main線程,然后再啟動(dòng)了MyThread線程,在MyThread線程中,又啟動(dòng)了MyThread1線程。但是由于讓MyThread1線程睡了1秒,模擬處理后續(xù)業(yè)務(wù),這樣他就比MyThread運(yùn)行完畢的時(shí)間晚一些。
現(xiàn)在,在代碼中加上CountDownLatch ,要讓MyThread1先運(yùn)行完畢,再讓MyThread繼續(xù)運(yùn)行。
package code; import java.util.concurrent.CountDownLatch; public class MyThread extends Thread { CountDownLatch countDownLatch = new CountDownLatch(1); public static void main(String[] args) { MyThread th = new MyThread(); Thread t1 = new Thread(th, "Mythread"); t1.start(); System.out.println(Thread.currentThread().getName()); } public void run() { Mythread1 th2 = new Mythread1(); Thread t2 = new Thread(th2, "Mythread1"); t2.start(); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.currentThread().getName()); } class Mythread1 extends Thread { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.currentThread().getName()); countDownLatch.countDown(); } } }
代碼寫法如上所示,大致分三步
1、我們先new一個(gè)CountDownLatch對(duì)象入?yún)⒃O(shè)置為1(我個(gè)人理解的這個(gè)就像是new一個(gè)數(shù)組一樣,什么時(shí)候數(shù)組清空了,那就可以讓被中斷的線程繼續(xù)運(yùn)行了)
2、在MyThread類中調(diào)用countDownLatch.await();讓當(dāng)前線程停止運(yùn)行。
3、在Mythread1類中調(diào)用countDownLatch.countDown()方法。當(dāng)Mythread1全部執(zhí)行完畢,再最后調(diào)用該方法,作用就是把我說的“數(shù)組”清空。
看看輸出的打印結(jié)果
結(jié)果如上圖,是符合預(yù)期的結(jié)果的。
最后再說下CountDownLatch countDownLatch = new CountDownLatch(1)的入?yún)ⅲ@塊設(shè)置的是1,那就需要調(diào)用一次countDownLatch.countDown()減去1。
如果是其他數(shù)字,那就要調(diào)用相應(yīng)的次數(shù),否則調(diào)用countDownLatch.await()的線程都不會(huì)被繼續(xù)執(zhí)行。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot和Docker實(shí)現(xiàn)微服務(wù)部署的方法
這篇文章主要介紹了Spring Boot和Docker實(shí)現(xiàn)微服務(wù)部署的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01Java使用嵌套循環(huán)模擬ATM機(jī)取款業(yè)務(wù)操作示例
這篇文章主要介紹了Java使用嵌套循環(huán)模擬ATM機(jī)取款業(yè)務(wù)操作,結(jié)合實(shí)例形式分析了Java模擬ATM機(jī)取款業(yè)務(wù)操作的相關(guān)流程控制、數(shù)值判斷等操作技巧,需要的朋友可以參考下2019-11-11IDEA在SpringBoot項(xiàng)目使用Maven打包后jar包太小問題及解決
這篇文章主要介紹了IDEA在SpringBoot項(xiàng)目使用Maven打包后jar包太小問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04java實(shí)現(xiàn)單鏈表中是否有環(huán)的方法詳解
本篇文章介紹了,用java實(shí)現(xiàn)單鏈表中是否有環(huán)的方法詳解。需要的朋友參考下2013-05-05mybatis resultmap 如何為對(duì)象賦值的調(diào)用順序
這篇文章主要介紹了mybatis resultmap 如何為對(duì)象賦值的調(diào)用順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01MyBatis與SpringMVC相結(jié)合實(shí)現(xiàn)文件上傳、下載功能
這篇文章主要介紹了MyBatis與SpringMVC相結(jié)合實(shí)現(xiàn)文件上傳、下載功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06