CountDownLatch
讓一些線程堵塞直到另一個線程完成一系列操作後才被喚醒。CountDownLatch 主要有兩個方法,當一個或多個線程調用 await 方法時,調用線程會被堵塞,其他線程調用 countDown 方法會將計數減一(調用 countDown 方法的線程不會堵塞),當計數其值變爲零時,因調用 await 方法被堵塞的線程會被喚醒,繼續執行。
假設我們有這麼一個場景,教室裏有班長和其他6個人在教室上自習,怎麼保證班長等其他6個人都走出教室在把教室門給關掉。
public class CountDownLanchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(() -> {
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + " 離開了教室...");
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println("班長把門給關了,離開了教室...");
}
}
CyclicBarrier
我們假設有這麼一個場景,每輛車只能坐一個人,當車滿了,就發車。
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(4, () -> {
System.out.println("車滿了,開始出發...");
});
for (int i = 0; i < 8; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 開始上車...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
Semaphore
假設我們有 3 個停車位,6 輛車去搶
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(() -> {
try {
semaphore.acquire(); // 獲取一個許可
System.out.println(Thread.currentThread().getName() + " 搶到車位...");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " 離開車位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 釋放一個許可
}
}).start();
}
}
}