文章目錄
- CountDownLatch 減少計數
-
- 場景
- CyclicBarrier 循環屏障
-
- 場景
- Semaphore 信号量
-
- 場景
JUC 中提供了三種常用的輔助類, 通過這些輔助類可以很好的解決線程數量過多時 Lock 鎖的頻繁操作
CountDownLatch 減少計數
- CountDownLatch 類可以設定一個計數器, 然後通過 countDown 方法來進行減1 的操作
- 使用await() 方法等待計數器為0, 然後繼續執行 await() 方法之後的語句
- 當一個或多個線程調用 await() 方法時, 這些線程會阻塞
- 其他線程調用 countDown 方法會将計數器減1(調用 countDown 方法的線程不會阻塞)
- 當計數器的值變為 0 時, 因 await() 方法阻塞的線程會被喚醒, 繼續執行
場景
6個同學陸續離開教室後班長才可以關門
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+ "同學離開教室");
countDownLatch.countDown();
}
},String.valueOf(i)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("班長鎖門啦!!!");
}
CyclicBarrier 循環屏障
CyclicBarrier 的構造方法的第一個參數是目标障礙數, 每次執行 CyclicBarrier.await() 方法, 障礙數就會加1
如果達到了目标障礙數, 就執行給定的屏障動作, 由最後一個進入屏障的線程執行
場景
6個同學陸續離開教室後班長才可以關門
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, new Runnable() {
@Override
public void run() {
System.out.println("班長鎖門啦!");
}
});
for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 同學離開教室了");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
},String.valueOf(i)).start();
}
}
Semaphore 信号量
- Semaphore 的構造方法中傳入的第一個參數是最大信号量(可以看成是最大線程池)
- 每個信号量隻能分發一個許可證
- 使用 acquire() 方法獲得許可證, 使用 release() 方法釋放許可證
場景
搶車位, 6輛汽車, 3個停車位
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
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();
}
}
},String.valueOf(i)).start();
}
}