這三個類都是基于AQS實現(xiàn)的類拦焚,也是面試中惩峒埽考的類,今天我們來學(xué)習(xí)一下這三個類的用法夺鲜。
- CountDownLatch:
Count:數(shù)數(shù)
Down:向下
Latch:門閂
顧名思義皆尔,這個類就是用來“倒計時”的,可以用來讓一個線程或多個線程等待多個線程币励。
下面看例子:
這個例子模擬的是同學(xué)下晚自習(xí)后慷蠕,班長關(guān)門的事件。正常情況是等所有同學(xué)都走完之后食呻,然后班長鎖門流炕,離開教室。這里新建五個線程模擬同學(xué)仅胞,主線程代表班長每辟。
public class Test {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "\t同學(xué)離開教室");
},String.valueOf(i)).start();
}
System.out.println(Thread.currentThread().getName() + "班長離開教室,鎖門");
}
}
1 同學(xué)離開教室
2 同學(xué)離開教室
3 同學(xué)離開教室
4 同學(xué)離開教室
main班長離開教室干旧,鎖門
5 同學(xué)離開教室
可以看到還剩一位同學(xué)沒走渠欺,班長就把門鎖上了,這肯定是不行的莱革,我們來用CountDownLatch來解決這個問題峻堰。
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(5);//設(shè)置初始門閂值,模擬還有五個同學(xué)在教室
for (int i = 1; i <= 5; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "\t同學(xué)離開教室");
countDownLatch.countDown();//每有一個同學(xué)離開教室盅视,門閂的值就減1
},String.valueOf(i)).start();
}
countDownLatch.await();//門閂的值減到0之前,main線程阻塞
System.out.println(Thread.currentThread().getName() + "班長離開教室旦万,鎖門");
}
}
1 同學(xué)離開教室
2 同學(xué)離開教室
3 同學(xué)離開教室
4 同學(xué)離開教室
5 同學(xué)離開教室
main班長離開教室闹击,鎖門
再無論怎么運行,main線程一定會等五個線程都運行之后才會輸出成艘。
-
CyclicBarrier
用來控制多個線程互相等待赏半,只有所有線程全部到達后,這些線程才會繼續(xù)執(zhí)行淆两。
CyclicBarrier有兩個構(gòu)造方法:public CyclicBarrier(int parties){ }
public CyclicBarrier(int parties,Runnable barrierAction){ }
當(dāng)所有的線程都到達時断箫,會觸發(fā)barrierAction
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Test {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new Thread(()-> {
System.out.println("召喚神龍");
}));//等待七個線程到位之后,執(zhí)行"System.out.println("召喚神龍");" 任務(wù)秋冰。
for (int i = 1; i <= 7; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "顆龍珠已經(jīng)收集");
try {
cyclicBarrier.await();//設(shè)置屏障仲义,等待所有線程到位
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
- semaphore
中文名:信號量,用于控制多個線程對互斥資源的訪問控制剑勾。
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); // 模擬總共有三個車位
/*
用六個線程來模擬有六輛車要搶占三個車位
*/
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
semaphore.acquire(); //搶占資源
System.out.println(Thread.currentThread().getName() + "\t搶到車位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "\t等待三秒后離開車位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//釋放資源
}
},String.valueOf(i)).start();
}
}
}
1 搶到車位
2 搶到車位
3 搶到車位
2 等待三秒后離開車位
3 等待三秒后離開車位
1 等待三秒后離開車位
4 搶到車位
6 搶到車位
5 搶到車位
4 等待三秒后離開車位
6 等待三秒后離開車位
5 等待三秒后離開車位