1. CountDownLatch
CountDownLatch
用給定的計數初始化。 [await
]方法阻塞,直到由於countDown()
方法的[調用]而導致當前計數達到零,之後所有等待線程被釋放,並且任何後續的await
[調用立即]返回。 這是一個一次性的現象 - 計數無法重置。 如果您需要重置計數的版本,請考慮使用[CyclicBarrier
] 。
package com.add;
import java.util.concurrent.CountDownLatch;
//計數器
public class CountDownLatchDemo01 {
public static void main(String[] args) throws InterruptedException {
//總數是6,類似於倒計時.參數設置爲6,即等待6個線程執行完畢
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"GO OUT");
countDownLatch.countDown();//-1
},String.valueOf(i)).start();
}
countDownLatch.await();//等待計數器歸零,然後在向下執行
System.out.println("close door");
}
}
原理:
//總數是6,類似於倒計時.參數設置爲6,即等待6個線程執行完畢
CountDownLatch countDownLatch = new CountDownLatch(6);
countDownLatch.countDown();//-1
countDownLatch.await();//等待計數器歸零,然後在向下執行
每次有線程調用countDown()數量減一假如計數器變爲0,countDownLatch.await()就會被喚醒,繼續執行!
2.CyclicBarrier
package com.add;
import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 集齊七龍珠召喚神龍
* 召喚控住的線程
*/
public class CyclicBarrierDemo02 {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召喚神龍成功!"); });
for (int i = 0; i < 7; i++) {
final int temp = i;
new Thread(()->{
// cyclicBarrier.getParties(); 由於數組自動遞增,這裏可以不設置
System.out.println(Thread.currentThread().getName()+"收集了第"+temp+"顆龍珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
3. Semaphore
semaphore:信號量
代碼:
package com.add;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo03 {
public static void main(String[] args) {
//限流的時候,會用到
Semaphore semaphore = new Semaphore(5, true);
for (int i = 0; i < 10; i++) {
new Thread(()->{
//acquire()都會阻塞(得到許可證),release()添加許可證,潛在地釋放阻塞獲取方(釋放)
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"搶到車位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"離開了車位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
原理: acquire()獲得,假設如果已經滿了,等待被釋放爲止
release()釋放,會將當前的信號量釋放+1,然後喚醒等待的線程!
作用:多個共享資源互斥的使用!併發限流,控制最大的限流數.