java多线程系列(八)—CountDownLatch和CyclicBarrie详解编程语言

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/15332.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论