先说一下CountDownLatch(看下列代码)
public class UseCountDownLatch {
public static void main(String[] args) {
final CountDownLatch countDown = new CountDownLatch(2);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("进入线程t1" + "等待其他线程处理完成...");
countDown.await();
System.out.println("t1线程继续执行...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t2线程进行初始化操作...");
Thread.sleep(3000);
System.out.println("t2线程初始化完毕,通知t1线程继续...");
countDown.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t3线程进行初始化操作...");
Thread.sleep(4000);
System.out.println("t3线程初始化完毕,通知t1线程继续...");
countDown.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t3.start();
}
运行结果:
CountDownLatch的主要作用是让一个线程阻塞等待,其他线程执行countDown方法,当countDown的值变为0的时候,该阻塞等待的线程才可向下运行,缺点是不能重用,上述代码中,定义了一个countDownLatch变量,初始值为2,三个线程启动,t1中执行countDownlatch的await方法,t1阻塞,t2和t3继续执行,sleep代表业务操作,当t2或t3执行countDown方法时,countdownlatch的值减1,当countdownlatch的值变为0时,t1才可以继续执行
下面说一下CyclicBarrier:
public class UseCyclicBarrier {
static class Runner implements Runnable {
private CyclicBarrier barrier;
private String name;
public Runner(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000 * (new Random()).nextInt(5));
System.out.println(name + " 准备OK.");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name + " Go!!");
}
}
public static void main(String[] args) throws IOException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(3); // 3
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new Thread(new Runner(barrier, "zhangsan")));
executor.submit(new Thread(new Runner(barrier, "lisi")));
executor.submit(new Thread(new Runner(barrier, "wangwu")));
executor.shutdown();
}
}
运行结果:
CyclicBarrier的作用是当多个线程都到达某个点时,多个线程才一起执行,如果有一个线程没到达barrier(可以理解为赛跑,当所有运动员都到达起点而且准备好的时候,才开始,barrier可以理解为起点),不同于countdownlatch,CyclicBarrier可以重用。如果把上述代码中的
CyclicBarrier barrier = new CyclicBarrier(3)改为4,则所有线程都会阻塞,不会执行下去,因为准备好的线程只有3个