CountDownLatch,一个同步辅助类,在完成一组其他线程汇总执行的操作前,它允许一个或多个线程一直等待
主要方法:
public CountDownLatch(int count); 构造方法参数指定了计数的次数
public void countDowm(): 当前线程调用此方法,则计数器减1
public void await(); 调用此方法会一致阻塞当前线程,直到计数器的值为0
示例中,
package demo1;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2);// 两个工人的协作
Executor executor = Executors.newFixedThreadPool(2);
executor.execute(new Worker("zhang san", 2000, latch));
executor.execute(new Worker("li si", 3000, latch));
/**
* 当主线程执行到这的时候,现在一共是有3个线程在同时执行
* 当主线程执行了latch.await()方法的时候,就会阻塞主线程,只到CountDownLatch的计数器变成0
* 而当其他线程执行了latch.countDown()方法后,才会把计数器减一.
* 所以这个时候,主线程就会等待计数器变成0后再执行
*/
latch.await();
System.out.println("all work done at " + sdf.format(new Date()));
}
/**
* 匿名内部类写法
* @author edgewalk
* @date 2017年6月8日
*/
static class Worker extends Thread {
String workerName;
int workTime;
CountDownLatch latch;
public Worker(String workerName, int workTime, CountDownLatch latch) {
this.workerName = workerName;
this.workTime = workTime;
this.latch = latch;
}
public void run() {
try {
System.out.println("Worker " + workerName + " do work begin at " + sdf.format(new Date()));
doWork();// 工作了
System.out.println("Worker " + workerName + " do work complete at " + sdf.format(new Date()));
} catch (Exception e) {
e.printStackTrace();
}finally {
if(latch != null) {
latch.countDown();
}
}
}
private void doWork() {
try {
Thread.sleep(workTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
打印结果:
Worker li si do work begin at 2017-06-08 23:11:38
Worker zhang san do work begin at 2017-06-08 23:11:38
Worker zhang san do work complete at 2017-06-08 23:11:40
Worker li si do work complete at 2017-06-08 23:11:41
all work done at 2017-06-08 23:11:41
补充:
如果我们不使用CountDownLatch的await()方法,那么all work done at ...这句话就不能保证在最后打印了