java API中提供了CountDownLatch类,它允许线程一直等待,知道等待操作结束。下面以一个视频会议等待人数为例。
1.视频会议类,实现Runnable接口。
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.",name);
controller.countDown();
//还没有到达的人数
System.out.printf("Videoconferencr has waitinf for %d participants\n",controller.getCount());
}
public void run() {
System.out.printf("Videoconference initialization:%d participants.\n",controller.getCount());
try {
//等待所有人到达,如果没有这句,则会在参与人没到达之前开始会议
controller.await();
System.out.printf("Videoconference:ALL participants has come\n");
System.out.print("Videoconference:Let is start...\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.与会者类
import java.util.concurrent.TimeUnit;
public class Participant implements Runnable{
private Videoconference conference;
public String name;
public Participant(Videoconference conference,String name){
this.conference = conference;
this.name = name;
}
@Override
public void run() {
long duration = (long)(Math.random()*10);
try {
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
conference.arrive(name);
}
}
3.主方法
package Thread03semaphone;
public class Main2 {
public static void main(String[] args){
Videoconference videoConference = new Videoconference(10);
Thread threadconference = new Thread(videoConference);
threadconference.start();
for(int i =0;i<10;i++){
Participant p = new Participant(videoConference,"Participant"+i);
Thread t = new Thread(p);
t.start();
}
}
}
当创建CountDownLatch对象时,通过构造器来初始化内部计数器(本例中为10),当countdown()方法被调用时,计数器将减1,当计数器为0时,countdownlatch将唤醒所有等待的线程。
注意点:
- CountDownLatch对象计数器一旦被初始化之后,就不可以修改。
- 他并不是用来保护临界资源或者同步代码块,只是用来同步多个任务的多个线程。
- CountDownLatch对象只能被使用一次,一旦计数器为0时,如果再需要使用,则需要重新New一个CountDownLatch对象。