小明,小紅埂材,小白三個(gè)人一起去登山,約好山腳下集合汤求,所有人到齊后開始登山俏险。
public class Test {
public static void fatherToClimb() {
System.out.println("小明去山下需要3小時(shí)");
}
public static void motherToClimb() {
System.out.println("小紅去山下需要2小時(shí)");
}
public static void meToClimb() {
System.out.println("小白去山下需要1小時(shí)");
}
public static void toClimb() {
System.out.println("一家人到齊了严拒,開始登山");
}
public static void main(String[] args) {
fatherToClimb();
motherToClimb();
meToClimb();
toClimb();
}
}
輸出結(jié)果:
這樣的輸出顯然是不正確的,因?yàn)樗麄內(nèi)齻€(gè)去山下是同時(shí)進(jìn)行的竖独,不是像現(xiàn)在這樣一共花費(fèi)了6個(gè)小時(shí)3人才到山下裤唠。
修改代碼:
public class Test {
public static void fatherToClimb() {
System.out.println("小明去山下需要3小時(shí)");
}
public static void motherToClimb() {
System.out.println("小紅去山下需要2小時(shí)");
}
public static void meToClimb() {
System.out.println("小白去山下需要1小時(shí)");
}
public static void toClimb() {
System.out.println("一家人到齊了,開始登山");
}
public static void main(String[] args) {
new Thread(){
public void run() {
fatherToClimb();
}
}.start();
new Thread(){
public void run() {
motherToClimb();
}
}.start();
new Thread(){
public void run() {
meToClimb();
}
}.start();
toClimb();
}
}
運(yùn)行結(jié)果:
看上去結(jié)果還是不正確莹痢,因?yàn)樾∶鞯搅松较戮烷_始登山了种蘸,顯然是錯(cuò)誤的。
import java.util.concurrent.CountDownLatch;
public class Test {
public static void fatherToClimb() {
System.out.println("小明去山下需要3小時(shí)");
}
public static void motherToClimb() {
System.out.println("小紅去山下需要2小時(shí)");
}
public static void meToClimb() {
System.out.println("小白去山下需要1小時(shí)");
}
public static void toClimb() {
System.out.println("一家人到齊了竞膳,開始登山");
}
public static class Mythread extends Thread{
public void run() {
fatherToClimb();
latch.countDown();
}
}
private static CountDownLatch latch = new CountDownLatch(3);
public static volatile int i = 3;
public static void main(String[] args) throws InterruptedException {
Mythread t1 = new Mythread();
t1.start();
new Thread() {
public void run() {
motherToClimb();
latch.countDown();
}
}.start();
new Thread() {
public void run() {
meToClimb();
latch.countDown();
}
}.start();
latch.await();
toClimb();
}
}
運(yùn)行結(jié)果:
避免使用忙等航瞭,我們使用了CountDowmLatch 實(shí)現(xiàn)了我們的需求。下面具體介紹一下這個(gè)哥們:
Latch閉鎖的意思坦辟,是一種同步的工具類刊侯。類似于一扇門:在閉鎖到達(dá)結(jié)束狀態(tài)之前,這扇門一直是關(guān)閉著的锉走,不允許任何線程通過滨彻,當(dāng)?shù)竭_(dá)結(jié)束狀態(tài)時(shí),這扇門會打開并允許所有的線程通過挪蹭。且當(dāng)門打開了疮绷,就永遠(yuǎn)保持打開狀態(tài)。
作用:可以用來確保某些活動(dòng)直到其他活動(dòng)都完成后才繼續(xù)執(zhí)行嚣潜。
使用場景:
1、例如我們上例中所有人都到達(dá)山下椅贱,然后開始登山;
2懂算、某個(gè)操作需要的資源初始化完畢
3、某個(gè)服務(wù)依賴的線程全部開啟等等...
CountDowmLatch是一種靈活的閉鎖實(shí)現(xiàn)庇麦,包含一個(gè)計(jì)數(shù)器计技,該計(jì)算器初始化為一個(gè)正數(shù),表示需要等待事件的數(shù)量山橄。countDown方法遞減計(jì)數(shù)器垮媒,表示有一個(gè)事件發(fā)生,而await方法等待計(jì)數(shù)器到達(dá)0航棱,表示所有需要等待的事情都已經(jīng)完成睡雇。