Java concurrency API提供了一个类允许一个或多个线程等待直到一系列操作执行完。它就是 CountDownLatch。 此类用一个整数初始化,该整数是线程将等待的操作数目。当一个线程想等待这些操作执行完,它调用 CountDownLatch 的 await 方法。 await 方法让线程睡到操作执行完。当其中一个操作执行完,使用 countDown() 方法减少 CountDownLatch 类的内部计数器。 当减到0,CountDownLatch 类将唤醒在 await() 方法中睡眠的所有线程。
本节的示例代码在 com.elanzone.books.noteeg.chpt3.sect04 package中
视频会议线程 : VideoConference
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(); System.out.printf("VideoConference: Waiting for %d participants.\n", controller.getCount()); }
System.out.printf("VideoConference: Initialization: %d participants.\n", controller.getCount()); try { controller.await(); System.out.printf("VideoConference: All the participants have come.\n"); System.out.printf("VideoConference: Let's start...\n"); } catch (InterruptedException e) { e.printStackTrace(); }
与会者线程 : Participant
private VideoConference conference; private String name; public Participant(VideoConference conference, String name) { this.conference = conference; this.name = name; }
long duration = (long) (Math.random() * 10); System.out.printf("%s: wait me for %d seconds\n", name, duration); try { TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } conference.arrive(name);
控制类 : Main
VideoConference conference = new VideoConference(10);
Thread threadConference = new Thread(conference); threadConference.start();
for (int i = 0; i < 10; i++) { Participant p = new Participant(conference, "Participant" + i); Thread t = new Thread(p); t.start(); }
CountDownLatch 类有 3 个基本元素:
不能重新初始化或修改 CountDownLatch 对象的内部计数器。当计数器被初始化,唯一能修改它的方法是 countDown() 方法。 当计数器到0,所有对 await() 方法的调用都立即返回,后续对 countDown() 方法的调用也不再有效。
和其他的同步机制相比,CountDownLatch 有以下区别: