輔助類,CountDownLatch,CyclicBarrier,Semaphore(訊號標; 旗語)
阿新 • • 發佈:2021-02-15
技術標籤:# JUC
CountDownLatch減法計數器演示
public static void main(String[] args) throws InterruptedException {
// 減法計數器, 構造器傳入初始的計數值
CountDownLatch countDownLatch = new CountDownLatch(6);
// 模擬7個人,6個學生,1個看門大爺,直到六個學生全部出去,再關門
for (int i = 1; i <= 6; i++) {
new Thread( () -> {
System.out.println(Thread.currentThread().getName() + "出去了");
countDownLatch.countDown();
System.out.println("ss");
}, String.valueOf(i)).start();
}
// 這個方法的作用: 等待計數器變為0,countDownLatch.await() 喚醒,再往下執行
countDownLatch.await( );
System.out.println("close door");
}
CyclicBarrier演示
public static void main(String[] args) {
// 加法計數器,集齊七顆龍珠召喚神龍
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("成功召喚神龍!!");
});
for (int i = 0; i < 7; i++) {
// 注意這裡直接訪問i是訪問不到的,因為new了一個物件
// 需要一個常量值來作為臨時i的替換,再訪問
// 當final變數是基本資料型別以及String型別時,如果在編譯期間能知道它的確切值,則編譯器會把它當做編譯期常量使用。
final int temp = i + 1;
new Thread(() -> {
System.out.printf("集齊了%d顆龍珠\n", temp);
// 等待七個執行緒全部開啟,再喚醒
try {
// 呼叫了await後,內部會自動加1,直到計數到7就會喚醒,繼續往下執行
cyclicBarrier.await();
System.out.println("ss");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
Semaphore演示
public static void main(String[] args) {
/**
* 訊號量
* 原理:
* acquire(): 獲取,如果沒有可獲取的資源了,等待,等待直到被釋放
* release(): 釋放,會將當前的訊號量釋放,然後喚醒等待的執行緒
* 例項: 3個停車位,6輛車
* 作用: 多個共享資源互斥的使用,併發限流,控制最大的執行緒數
* 應用: 網路限流
*/
Semaphore semaphore = new Semaphore(3);
// 開啟6個執行緒,相當於6輛車
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
// 獲取車位
// System.out.println(Thread.currentThread().getName()+"開始尋求車位");
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "獲得了車位!!!");
// 停車2s
TimeUnit.SECONDS.sleep(12);
System.out.println(Thread.currentThread().getName() + "離開了車位!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 釋放車位
semaphore.release();
}
}, String.valueOf(i)).start();
}
}