CountDownLatch,一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。
主要方法
?public CountDownLatch(int count);
?public void?countDown();
?public void?await() throws?InterruptedException
構造方法參數指定了計數的次數
countDown方法,當前線程調用此方法,則計數減一
awaint方法,調用此方法會一直阻塞當前線程,直到計時器的值為0
例子:
public class CountDownLatchDemo { final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static void main(String[] args) throws InterruptedException { CountDownLatch latch=new CountDownLatch(2);//兩個工人的協作 Worker worker1=new Worker("zhang san", 5000, latch); Worker worker2=new Worker("li si", 8000, latch); worker1.start();// worker2.start();// latch.await();//等待所有工人完成工作 System.out.println("all work done at "+sdf.format(new Date())); } static class Worker extends Thread{ String workerName; int workTime; CountDownLatch latch; public Worker(String workerName ,int workTime ,CountDownLatch latch){ this.workerName=workerName; this.workTime=workTime; this.latch=latch; } public void run(){ System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date())); doWork();//工作了 System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date())); latch.countDown();//工人完成工作,計數器減一 } private void doWork(){ try { Thread.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } } }
輸出:
Worker zhang san do work begin at 2011-04-14 11:05:11
Worker li si do work begin at 2011-04-14 11:05:11
Worker zhang san do work complete at 2011-04-14 11:05:16
Worker li si do work complete at 2011-04-14 11:05:19
all work done at 2011-04-14 11:05:19
?
CountDownLatch類有3個基本元素:
- 初始值決定CountDownLatch類需要等待的事件的數量。
- await() 方法, 被等待全部事件終結的線程調用。
- countDown() 方法,事件在結束執行后調用。
當創建 CountDownLatch 對象時,對象使用構造函數的參數來初始化內部計數器。每次調用 countDown() 方法, CountDownLatch 對象內部計數器減一。當內部計數器達到0時, CountDownLatch 對象喚醒全部使用 await() 方法睡眠的線程們。
不可能重新初始化或者修改CountDownLatch對象的內部計數器的值。一旦計數器的值初始后,唯一可以修改它的方法就是之前用的 countDown() 方法。當計數器到達0時, 全部調用 await() 方法會立刻返回,接下來任何countDown() 方法的調用都將不會造成任何影響。
此方法與其他同步方法有這些不同:
CountDownLatch 機制不是用來保護共享資源或者臨界區。它是用來同步一個或者多個執行多個任務的線程。它只能使用一次。像之前解說的,一旦CountDownLatch的計數器到達0,任何對它的方法的調用都是無效的。如果你想再次同步,你必須創建新的對象。
CountDownLatch 類有另一種版本的 await() 方法,它是:
- await(long time, TimeUnit unit): 此方法會休眠直到被中斷; CountDownLatch 內部計數器到達0或者特定的時間過去了。TimeUnit 類包含了:DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, 和 SECONDS.