并发控制(5)使用CountDownLatch来控制多线程下的程序流程
CountDownLatch和CyclicBarrier的区别,其实比较简单,CountDownLatch对执行任务的线程。比如有A,B,C三个线程,那么如果A是设置了countDown.await()这个方法,那么B和C就只能等到A了,什么时候A准备好了,那么B和C才可以执行.
典型的场景就是,比如A需要从远程服务器拿到某个资源,然后B和C的执行,需要依赖A这个资源,但是又可能,A执行的时候,拿到的资源还是空的或者没有就绪,那么只有通过在主线程里,另外起一个线程,比如叫D吧,他循环判断A请求的资源是否就绪,而在主线程里在B和C执行以前,统一设置一个 countDown.await()方法。只有当D确认资源状态以后,并且调用了 countDown.countDown(2) 这里是2是假设的,到0,就表示OK了,那么被等待的方法才能继续执行下去
而 CyclicBarrier还是按照那个运动员比赛的例子,A B C三个都要准备好了,不然没有办法继续下去.
有如下代码
import java.util.concurrent.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();
}
}