java 併發API提供了CountDownLatch類,它是一個同步輔助類。在完成一組正在其它線程中執行的操做之
前,它容許線程一直等等。這個類使用一個整數進行初始化,這個整數就是線程要等等完成的操做的數目。
當一個線程要等待某些操做先執行完成時,須要調用await()方法,這個方法讓線程進入休眠直到等待的全部
操做都完成。當某一個操做完成,它將調用cuntDown()方法將CountDownLatch類內部計數器減1。當計數
器變成0的時候,CountDownLatch類將喚醒全部調用await()方法而進入休眠的線程。java
CountDownLatch 對象的內部計數器被初始化以後就不能被再次初始化或者修改。
一旦計數器被初始化後,惟一能改變參數值的方法是countDown(),當計數器到達0
時,全部因調用await()方法而等待的線程當即被喚醒,再執行countDown()將不起做用。編程
/** * 視頻會議,當全部參與者都到齊纔開始 */ static class VideoConference implements Runnable { private final CountDownLatch controller; public VideoConference(int number) { this.controller = new CountDownLatch(number); } //每個參與者到場時,這個方法將被調用 public void arrive(String people) { this.controller.countDown(); System.out.println(people + "到了,還差" + this.controller.getCount() + "位。"); } @Override public void run() { System.out.println("此次會議共" + this.controller.getCount() + "人蔘加"); try { controller.await(); System.out.println("會議開始了..."); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 參與者 */ static class People implements Runnable { private final String name; private final VideoConference videoConference; public People(String name, VideoConference videoConference) { this.name = name; this.videoConference = videoConference; } @Override public void run() { long duration = (long) (Math.random() * 10); try { TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } this.videoConference.arrive(this.name); } } public static void main(String[] args) { VideoConference videoConference = new VideoConference(5); new Thread(videoConference).start(); Stream.of("張三", "李四", "王五", "陳六", "趙七").forEach(name -> { new Thread(new People(name, videoConference)).start(); }); }
此次會議共5人蔘加
李四到了,還差4位。
趙七到了,還差3位。
陳六到了,還差2位。
張三到了,還差1位。
王五到了,還差0位。
會議開始了...併發
《摘自 java7併發編程實戰》dom