CountDownLatch
前言:如有不正确的地方,还望指正。
什么是CountDownLatch
-
允许一个或多个线程等待其他线程完成后再执行,比如说我们要等待人齐了才一起吃饭
核心方法
-
CountDownLatch(int count):构造方法,初始计数器
-
await():使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断
-
countDown():计数器减一
-
getCount():返回当前计数
使用过程
-
CountDownLatch内部有一个线程数量计数器,当一个(或多个)线程执行await方法后等待,其他的线程完成任务后,计数器减一。如果此时计数器大于0,那么等待的线程继续等待。如果为0,表示其他线程任务执行完成,此时等待的线程会被唤醒
CountDownLatch使用
import java.util.concurrent.CountDownLatch;
public class Demo {
public static void main(String[] args) {
CountDownLatch cd = new CountDownLatch(3);
EatThread et=new EatThread(cd);
PeopleComeThread father=new PeopleComeThread(cd,"father");
PeopleComeThread mother=new PeopleComeThread(cd,"mother");
PeopleComeThread son=new PeopleComeThread(cd,"son");
et.start();
father.start();
mother.start();
son.start();
}
}
class EatThread extends Thread
{
CountDownLatch cd;
public EatThread(CountDownLatch cd)
{
this.cd=cd;
}
public void run()
{
System.out.println("等待人齐再吃饭");
try {
cd.await();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("好了,人齐开饭");
}
}
class PeopleComeThread extends Thread
{
CountDownLatch cd;
String name;
public PeopleComeThread(CountDownLatch cd,String name)
{
this.cd=cd;
this.name=name;
}
public void run()
{
System.out.println(name+"即将到达");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
cd.countDown();
}
}
-
输出结果
等待人齐再吃饭 mother即将到达 father即将到达 son即将到达 好了,人齐开饭
-
代码中我们只用到一个CountDownLatch对象,并初始化了一个计数器,执行await的线程等待,当执行一次countDown后,计数器减一,计数器为0后,等待的线程被唤醒
CyclicBarrier
什么是CyclicBarrier
-
它允许一组线程互相等待,直到到达某个公共屏障点 ,也就是说多个线程等待,达到一个点的时候唤醒。
核心方法
-
CyclicBarrier(int parties),屏障(barrier)拦截的线程数,也就是parties个线程执行await方法后,这几个线程才能集体唤醒
-
CyclicBarrier(int parties, Runnable barrierAction),barrierAction到达屏障后执行的任务
使用过程
-
同样是内部有一个计数器,初始化拦截的线程数,每一个线程执行awiat,计数器就会减一,当计数器为0的时候说明到达屏障,线程唤醒
CyclicBarrier使用
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Demo2 {
public static void main(String[] args) {
CyclicBarrier cb=new CyclicBarrier(3);
PeopleComeThread father=new PeopleComeThread(cb,"father");
PeopleComeThread mother=new PeopleComeThread(cb,"mother");
PeopleComeThread son=new PeopleComeThread(cb,"son");
father.start();
mother.start();
son.start();
}
}
class PeopleComeThread extends Thread
{
CyclicBarrier cb;
String name;
public PeopleComeThread(CyclicBarrier cb,String name)
{
this.cb=cb;
this.name=name;
}
public void run()
{
System.out.println(name+"等待其他人到齐,等到3个人都到齐就可以吃饭");
try {
cb.await();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("人齐了,"+name+"开始吃饭");
}
}
-
输出结果
mother等待其他人到齐,等到3个人都到齐就可以吃饭 father等待其他人到齐,等到3个人都到齐就可以吃饭 son等待其他人到齐,等到3个人都到齐就可以吃饭 人齐了,son开始吃饭 人齐了,mother开始吃饭 人齐了,father开始吃饭
-
代码中我们用到了CyclicBarrier对象,并给他初始化拦截的线程数为n,执行await的线程等待,当n个线程都执行await方法后,这n个线程唤醒
比较
-
两者都是一种消息等待通知机制,目的都是解决什么时候让等待的线程的唤醒
-
CountDownLatch不能重置计数,CyclicBarrier可以
-
作者:jiajun 出处: http://www.cnblogs.com/-new/
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/15332.html