JAVA多線(xiàn)程CountDownLatch使用詳解
前序:
上周測(cè)試給開(kāi)發(fā)的同事所開(kāi)發(fā)的模塊提出了一個(gè)bug,并且還是偶現(xiàn)。
經(jīng)過(guò)仔細(xì)查看代碼,發(fā)現(xiàn)是在業(yè)務(wù)中啟用了多線(xiàn)程,2個(gè)線(xiàn)程同時(shí)跑,但是新啟動(dòng)的2個(gè)線(xiàn)程必須保證一個(gè)完成之后另一個(gè)再繼續(xù)運(yùn)行,才能消除bug。
什么時(shí)候用?
多線(xiàn)程是在很多地方都會(huì)用到的,但是我們?nèi)绻胍獙?shí)現(xiàn)在某個(gè)特定的線(xiàn)程運(yùn)行完之后,再啟動(dòng)另外一個(gè)線(xiàn)程呢,這個(gè)時(shí)候CountDownLatch就可以派上用場(chǎng)了
怎么用?
先看看普通的多線(xiàn)程代碼:
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類(lèi),然后在MyThread類(lèi)內(nèi)部又寫(xiě)了一個(gè)MyThread1類(lèi),同樣也是繼承了Thread類(lèi),并且在run方法里面讓它睡1秒,這樣運(yùn)行代碼,就會(huì)打印出:

從上面的輸出順序可以看出,先是啟動(dòng)了main線(xiàn)程,然后再啟動(dòng)了MyThread線(xiàn)程,在MyThread線(xiàn)程中,又啟動(dòng)了MyThread1線(xiàn)程。但是由于讓MyThread1線(xiàn)程睡了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();
}
}
}
代碼寫(xiě)法如上所示,大致分三步
1、我們先new一個(gè)CountDownLatch對(duì)象入?yún)⒃O(shè)置為1(我個(gè)人理解的這個(gè)就像是new一個(gè)數(shù)組一樣,什么時(shí)候數(shù)組清空了,那就可以讓被中斷的線(xiàn)程繼續(xù)運(yùn)行了)
2、在MyThread類(lèi)中調(diào)用countDownLatch.await();讓當(dāng)前線(xiàn)程停止運(yùn)行。
3、在Mythread1類(lèi)中調(diào)用countDownLatch.countDown()方法。當(dāng)Mythread1全部執(zhí)行完畢,再最后調(diào)用該方法,作用就是把我說(shuō)的“數(shù)組”清空。
看看輸出的打印結(jié)果

結(jié)果如上圖,是符合預(yù)期的結(jié)果的。
最后再說(shuō)下CountDownLatch countDownLatch = new CountDownLatch(1)的入?yún)ⅲ@塊設(shè)置的是1,那就需要調(diào)用一次countDownLatch.countDown()減去1。
如果是其他數(shù)字,那就要調(diào)用相應(yīng)的次數(shù),否則調(diào)用countDownLatch.await()的線(xiàn)程都不會(huì)被繼續(xù)執(zhí)行。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解Java多線(xiàn)程編程中CountDownLatch阻塞線(xiàn)程的方法
- java使用CountDownLatch等待多線(xiàn)程全部執(zhí)行完成
- 如何使用CountDownLatch同步j(luò)ava多線(xiàn)程
- Java countDownLatch如何實(shí)現(xiàn)多線(xiàn)程任務(wù)阻塞等待
- java多線(xiàn)程CountDownLatch與線(xiàn)程池ThreadPoolExecutor/ExecutorService案例
- Java多線(xiàn)程之同步工具類(lèi)CountDownLatch
- Java多線(xiàn)程同步工具類(lèi)CountDownLatch詳解
相關(guān)文章
Java實(shí)現(xiàn)ModbusTCP通信功能
使用ModbusTCP實(shí)現(xiàn)和硬件設(shè)備通信功能,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-08-08
Spring中的@PostConstruct注解使用方法解析
這篇文章主要介紹了Spring中的@PostConstruct注解使用方法解析,@PostConstruct注解是用來(lái)處理在@Autowired注入屬性后init()方法之前,對(duì)一些零散的屬性進(jìn)行賦值的注解,需要的朋友可以參考下2023-11-11
SpringBoot集成Apache POI實(shí)現(xiàn)Excel的導(dǎo)入導(dǎo)出
Apache POI是一個(gè)流行的Java庫(kù),用于處理Microsoft Office格式文件,包括Excel文件,本文主要介紹了SpringBoot集成Apache POI實(shí)現(xiàn)Excel的導(dǎo)入導(dǎo)出,具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
Java ExecutorServic線(xiàn)程池異步實(shí)現(xiàn)流程
這篇文章主要介紹了Java ExecutorServic線(xiàn)程池異步實(shí)現(xiàn)流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
基于java.lang.IllegalArgumentException異常報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了基于java.lang.IllegalArgumentException異常報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
SpringBoot中maven項(xiàng)目打成war包部署在linux服務(wù)器上的方法
這篇文章主要介紹了SpringBoot中maven項(xiàng)目打成war包部署在linux服務(wù)器上的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05

