java並發之同步輔助類CountDownLatch
阿新 • • 發佈:2018-03-17
java 同步 多線程 CountDownLatch
含義:
CountDownLatch可以理解為一個計數器在初始化時設置初始值,當一個線程需要等待某些操作先完成時,需要調用await()方法。這個方法讓線程進入休眠狀態直到等待的所有線程都執行完成。每調用一次countDown()方法內部計數器減1,直到計數器為0時喚醒。這個可以理解為特殊的CyclicBarrier。線程同步點比較特殊,為內部計數器值為0時開始。
方法:
核心方法兩個:countDown()和await()
countDown():使CountDownLatch維護的內部計數器減1,每個被等待的線程完成的時候調用
await():線程在執行到CountDownLatch的時候會將此線程置於休眠
例子
開會的例子:會議室裏等與會人員到齊了會議才能開始。
import java.util.concurrent.CountDownLatch; public class VideoConference implements Runnable { private final CountDownLatch controller; 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()); } @Override 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();
}
}
}
海量視頻
java並發之同步輔助類CountDownLatch