CountDownLatch能夠理解爲一個計數器在初始化時設置初始值,當一個線程須要等待某些操做先完成時,須要調用await()方法。這個方法讓線程進入休眠狀態直到等待的全部線程都執行完成。每調用一次countDown()方法內部計數器減1,直到計數器爲0時喚醒。這個能夠理解爲特殊的CyclicBarrier。線程同步點比較特殊,爲內部計數器值爲0時開始。vue
方法:java
核心方法兩個:countDown()和await()spring
countDown():使CountDownLatch維護的內部計數器減1,每一個被等待的線程完成的時候調用springboot
await():線程在執行到CountDownLatch的時候會將此線程置於休眠dom
例子ide
開會的例子:會議室裏等與會人員到齊了會議才能開始。測試
import java.util.concurrent.CountDownLatch;ui
public class VideoConference implements Runnable {spa
private final CountDownLatch controller;.net
public VideoConference(int number) {
controller = new CountDownLatch(number);
}
public void arrive(String name) {
System.out.printf("%s has arrived.\n", name);
controller.countDown();// 調用countDown()方法,使內部計數器減1
System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount());
}
public void run() {
System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount());
try {
controller.await();// 等待,直到CoutDownLatch計數器爲0
System.out.printf("VideoConference: All the participants have come\n");
System.out.printf("VideoConference: Let's start...\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
參加會議人員類
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintQueue {
//信號量
private Semaphore semaphore;
//是否空閒打印機
private boolean freePrinters[];
private Lock lockPrinters;
public PrintQueue(){
//初始化三個信號
semaphore=new Semaphore(3);
//三臺空閒打印機
freePrinters=new boolean[3];
for (int i=0; i<3; i++){
freePrinters[i]=true;
}
lockPrinters=new ReentrantLock();
}
public void printJob (Object document){
try {
//獲取信號量
semaphore.acquire();
int assignedPrinter=getPrinter();
Long duration=(long)(Math.random()*10);
System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
TimeUnit.SECONDS.sleep(duration);
freePrinters[assignedPrinter]=true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// Free the semaphore
semaphore.release();
}
}
private int getPrinter() {
int ret=-1;
try {
lockPrinters.lock();
for (int i=0; i<freePrinters.length; i++) {
if (freePrinters[i]){
ret=i;
freePrinters[i]=false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lockPrinters.unlock();
}
return ret;
}
}
測試類:
public class CountDownLatchMain {
public static void main(String[] args) {
VideoConference conference = new VideoConference(10);
Thread threadConference = new Thread(conference);
threadConference.start();// 開啓await()方法,在內部計數器爲0以前線程處於等待狀態
for (int i = 0; i < 10; i++) {
Participant p = new Participant(conference, "Participant " + i);
Thread t = new Thread(p);
t.start();
}
}
}
海量視頻獲取 springboot springcloud vue 視頻