CountDownLatch和CyclicBarrier都是控制并发而生,都在java.util.concurrent包下。
CountDownLatch
简单称为计数器,适合1个或者多个线程等待其他线程执行完毕后自己开始执行。其中最主要的方法是await和countDown,调用await()的线程如果CountDownLatch内部count变量不为0,则一直阻塞,直到为0,并且可以有多个线程调用await(),也就是多个线程同时等待。
下面的例子先创建两个线程,一直等待,然后启动10个线程对CountDownLatch进行减少。10次countDown()后,前两个线程才可以运行。
public class Main2 {
static CountDownLatch countDownLatch = new CountDownLatch(10);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 2; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread()+" start");
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " end");
}).start();
}
Thread.sleep(2000);
startThreads();
}
private static void startThreads() {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
countDownLatch.countDown();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
CyclicBarrier
和CountDownLatch类似,也实现了线程间的计数等待,同样调用其await()让线程阻塞,但是区别是只有当其他线程也调用await()直到数量为计数总数时才得到运行。并且提供了复位方法reset()。
比如和朋友开黑,5名朋友依次来网吧,来的人要等待没来的,到齐后,一起说声联盟万岁。
public class Main2 {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
System.out.println("可以开黑了");
});
for (int i = 0; i < 5; i++) {
new Friend(cyclicBarrier).start();
System.out.println("还剩" + (cyclicBarrier.getParties() - cyclicBarrier.getNumberWaiting()) + " 人");
Thread.sleep(1000);
}
}
static class Friend extends Thread {
CyclicBarrier mCyclicBarrier;
public Friend(CyclicBarrier cyclicBarrier) {
mCyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
super.run();
String msg = (mCyclicBarrier.getParties() - mCyclicBarrier.getNumberWaiting() == 1) ? "最后一位到了" : "等待其他队友";
System.out.println(Thread.currentThread() + msg);
try {
mCyclicBarrier.await();
System.out.println("联盟万岁");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
还剩5 人
Thread[Thread-0,5,main]等待其他队友
还剩4 人
Thread[Thread-1,5,main]等待其他队友
还剩3 人
Thread[Thread-2,5,main]等待其他队友
还剩2 人
Thread[Thread-3,5,main]等待其他队友
还剩1 人
Thread[Thread-4,5,main]最后一位到了
可以开黑了
联盟万岁
联盟万岁
联盟万岁
联盟万岁
联盟万岁
区别
对于CountDownLatch,等待条件完成后执行者是其他线程,而CyclicBarrier是本身,并且CyclicBarrier可循环使用,提供了reset()来复位,但是会导致await()的线程抛出BrokenBarrierException异常。
也就是说CountDownLatch是一个或者多个线程在等待其他线程,而CyclicBarrier是多个线程互相等待。
HouXinLin_CSDN 发布了18 篇原创文章 · 获赞 7 · 访问量 6053 私信 关注