1.CountDownLatch
讓一些線程堵塞直到另一個線程完成一系列操作後才被喚醒。CountDownLatch 主要有兩個方法,當一個或多個線程調用 await 方法時,調用線程會被堵塞,其他線程調用 countDown 方法會將計數減一(調用 countDown 方法的線程不會堵塞),當計數其值變爲零時,因調用 await 方法被堵塞的線程會被喚醒,繼續執行。
案例:
假設有這麼一個場景,教室裏有班長和其他6個人在教室上自習,怎麼保證班長等其他6個人都走出教室在把教室門給關掉。
package com.juc.interview;
import java.util.concurrent.CountDownLatch;
/**
* @description: juc下的類學習
* @author: Mr.Li
* @create: 2019-09-29 21:25
**/
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + "離開了教室");
}, String.valueOf(i)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("班長把門關上了...");
}
}
運行結果:
1離開了教室
2離開了教室
4離開了教室
5離開了教室
3離開了教室
6離開了教室
班長把門關上了...
Process finished with exit code 0
2.CyclicBarrier
字面意思是可循環(Cyclic)使用的屏障(Barrier)。他要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障纔會開門,所有被屏障攔截的線程纔會繼續幹活,線程進入屏障通過CyclicBarrier的await()方法。
案例:
我們假設有這麼一個場景,每輛車只能坐4個人,當車滿了,就發車。
package com.juc.interview;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @description: CyclicBarrier學習
* @author: Mr.Li
* @create: 2019-09-29 21:57
**/
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(4, ()->{
System.out.println("車滿了,開始發車");
});
for (int i = 1; i <= 8; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "成功上車");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
運行結果:
1成功上車
2成功上車
4成功上車
5成功上車
車滿了,開始發車
7成功上車
3成功上車
8成功上車
6成功上車
車滿了,開始發車
Process finished with exit code 0
3.Semaphore
信號量主要用於兩個目的,一個是用於多個共享資源的互斥作用,另一個用於併發線程數的控制。
案例:
假設我們有 3 個停車位,6 輛車去搶
package com.juc.interview;
import java.util.concurrent.Semaphore;
/**
* @description: SemaphoreDemo學習
* @author: Mr.Li
* @create: 2019-09-29 22:07
**/
public class SemaphoreDemo {
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() + "搶到車位");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + "離開車位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}).start();
}
}
}
運行結果:
Thread-0搶到車位
Thread-2搶到車位
Thread-1搶到車位
Thread-2離開車位
Thread-0離開車位
Thread-1離開車位
Thread-4搶到車位
Thread-3搶到車位
Thread-5搶到車位
Thread-3離開車位
Thread-4離開車位
Thread-5離開車位
Process finished with exit code 0
每日一言:
人生就像射箭,而夢想就像箭靶子,如果你連箭靶子都找不到的話,那每天的拉弓就毫無意義