CountDownLatch:允许一个或者多个线程等待其他线程完成操作。主线程需要等待其他线程完成后才能操作。
要实现这样的功能,也可以使用Thread.join()方法,让当前线程等待调用join方法的线程执行结束后才能继续执行。原理是:当前线程不断地检查join线程是否存活,直到join线程中止,线程的this.notifyAll()方法将被调用。
CountDownLatch就是实现了join的功能,构造函数会接受一个int参数作为计数器,想等待N个线程或者一个线程的N个执行步骤完成就传入N,使用CountDownLatch的countDown方法,N会减1,await方法会阻塞当前线程,直到N变为0。也可以使用await来定时。
借鉴其他人的博客改的一个小例子:
import java.util.concurrent.CountDownLatch;
public class ThreadCountDownLatch {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(2); //两个线程协同合作
Thread worker1 = new myWork("worker1", 3000, latch);
Thread worker2 = new myWork("worker2", 5000, latch);
worker1.start();
worker2.start();
try {
latch.await(); //等待所有的线程完成任务
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("the project is ended");
}
}
class myWork extends Thread{
private CountDownLatch latch;
private String name;
private int workTime;
public myWork(String name, int workTime, CountDownLatch latch) {
this.name = name;
this.latch = latch;
this.workTime = workTime;
}
@Override
public void run() {
System.out.println("I'm " + name + ", my job is started.");
try {
Thread.sleep(workTime);
System.out.println(name + "'s job is done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
latch.countDown(); //一个线程完成,计数器减1
}
}
}
输出结果:
I'm worker1, my job is started.
I'm worker2, my job is started.
worker1's job is done!
worker2's job is done!
the project is ended
(看见没,两个线程中间都休眠了不短的时间,但是主线程的输出语句会一直等到两个线程执行结束之后才执行)
该工具类的关键点都在代码中加以注释了。
在这加上join的用法,只贴上了一小部分的代码段:
Thread mrCheng = new KeyPersonThread();
try {
mrCheng.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行完毕");
System.out.println("再见!");
这可以保证最后两个输出语句不会再mrCheng线程结束之前被执行。