CountDownLatch可用于一个线程等待另外一些线程做了一些事后再做自己的事。做事的线程做完事后报一下数:将一个初数值减1,等这个数值变成0时,等待的线程就可以做自己的事。
用join()也能完成相同的目标。但join()意味着必须等待做事线程终止自己才能动手,CountDownLatch没有这个限制,做事线程再报完数后还可以继续做自己的事。
package player.kent.chen.learn.countdownlatch;
import java.util.concurrent.CountDownLatch;
public class HelloLatch {
private static class Begger implements Runnable {
private CountDownLatch latch;
public Begger(CountDownLatch latch) {
super();
this.latch = latch;
}
public void run() {
try {
System.out.println("我是乞丐,要钱吃饭");
latch.await(); //等待别人报数完毕
System.out.println("我是乞丐,钱要够了,现在去买吃的");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
private static final class Walker implements Runnable {
private CountDownLatch latch;
public Walker(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
takeTime(3000l);
System.out.println("我是行人" + Thread.currentThread().getName()
+ " 我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱");
latch.countDown(); //给完钱后,报数
takeTime(10000l); //报完数后,继续做自己的事,线程仍然活着
System.out.println("我是行人" + Thread.currentThread().getName()
+ " 给完钱后,我在无边的人海中继续前行直到永远。。。");
takeTime(Long.MAX_VALUE);
}
private void takeTime(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) throws InterruptedException {
int count = 3;
CountDownLatch latch = new CountDownLatch(count);
new Thread(new Begger(latch)).start();
Thread.sleep(3000);
Thread[] threads = new Thread[count];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Walker(latch));
threads[i].setName("walker" + i);
}
for (Thread thread : threads) {
thread.start();
System.out.println(thread.getName() + " 已经动身了 ");
Thread.sleep(1000l); //动身时间间隔一秒
}
}
}
执行结果:
我是乞丐,要钱吃饭
walker0 已经动身了
walker1 已经动身了
walker2 已经动身了
我是行人walker0 我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱
我是行人walker1 我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱
我是行人walker2 我走到乞丐跟前花了3秒钟,然后给了乞丐一块钱
我是乞丐,钱要够了,现在去买吃的
我是行人walker0 给完钱后,我在无边的人海中继续前行直到永远。。。
我是行人walker1 给完钱后,我在无边的人海中继续前行直到永远。。。
我是行人walker2 给完钱后,我在无边的人海中继续前行直到永远。。。
同时各行人线程仍处于alive状态。