CountDownLatch
可以把它看作一个计数器,这个计数器的操作是原子操作,同时只能有一个线程去减这个计数器里面的值。
向CountDownLatch对象设置一个初始的数字作为计数值,调用 await() 会阻塞,直到这个计数器的计数值被其他的线程减为0。
应用场景
有一个任务想要往下执行,但必须要等到其他的任务执行完毕。调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
代码
public class Test {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
// 线程1 启动
new Thread() {
public void run() {
try {
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
;
}.start();
// 线程2 启动
new Thread(() -> {
try {
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
try {
latch.await(); // 主线程阻塞
System.out.println("2个子线程已经执行完毕, 继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CyclicBarrier
“循环栅栏”:一个可循环利用的屏障。
它的作用就是会让所有线程都等待完成后才会继续下一步行动。
现实生活中我们经常会遇到这样的情景,在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,比赛时要等运动员都上场后才开始。
利用CyclicBarrier类可以实现一组线程相互等待,当所有线程都到达某个屏障点后再进行后续的操作。
public class Test {
static class TaskThread extends Thread {
CyclicBarrier barrier;
public TaskThread(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(getName() + " 到达栅栏 A");
barrier.await(); // 所有线程到达栅栏A,继续执行
Thread.sleep(2000);
barrier.await(); // 所有线程到达栅栏B,继续执行
System.out.println(getName() + " 冲破栅栏 B");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int threadNum = 5;
CyclicBarrier barrier = new CyclicBarrier(threadNum);
for (int i = 0; i < threadNum; i++) {
new TaskThread(barrier).start();
}
}
}
countDownLatch
CyclicBarrier 原理(秒懂)
标签:juc,barrier,Thread,await,线程,CyclicBarrier,public From: https://www.cnblogs.com/zrzct/p/18637809