• CountDownLatch


      CountDownLatch也叫闭锁,在JDK1.5被引入,允许一个或多个线程等待其他线程完成操作后再执行。

      CountDownLatch内部会维护一个初始值为线程数量的计数器,主线程执行await方法,如果计数器大于0,则阻塞等待。

      当一个线程完成任务后,计数器值减1。当计数器为0时,表示所有的线程已经完成任务,等待的主线程被唤醒继续执行。

      CountDownLatch使用AQS的方式与Semaphore相似:在同步状态中保存的是当前的计数值。

    闭锁的作用:

      确保某个计算在其需要的所有资源都被初始化之后才继续执行。

      确保某个服务在其依赖的所有其他服务都已经启动之后才启动。

      等待直到某个操作的所有参与者都就绪再继续执行。

      CountDownLatch还可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

    和CyclicBarrier的区别:

      CyclicBarrier 允许一系列线程相互等待对方到达一个点,正如 barrier 表示的意思,该点就像一个栅栏,先到达的线程被阻塞在栅栏前,必须等到所有线程都到达了才能够通过栅栏;

      CyclicBarrier 持有一个变量 parties,表示需要全部到达的线程数量;先到达的线程调用 barrier.await 方法进行等待,一旦到达的线程数达到 parties 变量所指定的数,栅栏打开,所有线程都可以通过;

      CyclicBarrier 构造方法接受另一个 Runnable 类型参数 barrierAction,该参数表明再栅栏被打开的时候需要采取的动作,null 表示不采取任何动作,注意该动作将会在栅栏被打开而所有线程接着运行前被执行

      CyclicBarrier 是可重用的,当最后一个线程到达的时候,栅栏被打开,所有线程通过之后栅栏重新关闭,进入下一代;

      CyclicBarrier.reset 方法能够手动重置栅栏,此时正在等待的线程会收到 BrokenBarrierException异常。

     1 public class Test {
     2      public static void main(String[] args) {   
     3          final CountDownLatch latch = new CountDownLatch(2);
     4           
     5          new Thread(){
     6              public void run() {
     7                  try {
     8                    。。。
     9                     latch.countDown();
    10                 } catch (InterruptedException e) {
    11                     e.printStackTrace();
    12                 }
    13              };
    14          }.start();
    15           
    16          new Thread(){
    17              public void run() {
    18                  try {
    19                      。。。
    20                      latch.countDown();
    21                 } catch (InterruptedException e) {
    22                     e.printStackTrace();
    23                 }
    24              };
    25          }.start();
    26           
    27          try {
    28             System.out.println("等待2个子线程执行完毕...");
    29             latch.await();
    30             System.out.println("2个子线程已经执行完毕");
    31             System.out.println("继续执行主线程");
    32         } catch (InterruptedException e) {
    33             e.printStackTrace();
    34         }
    35      }
    36 }

  • 相关阅读:
    Java泛型 T.class的获取
    Android ant自动打包脚本:自动替换友盟渠道、版本号、包名
    验证:mysql AUTO_INCREMENT 默认值是1
    双重OAuth 2.0架构
    使用coding、daocloud和docker打造markdown纯静态博客
    创业小坑:内网域名 在windows下能nslookup,但ping不通,也无法访问。而在linux下正常。
    freeradius 安装出错的解决办法
    与锤子手机HR的对话——创业没有联合创始人,CTO 等高管会把它当做自己的事业吗?
    LBS数据分析:使用地图展示统计数据——麻点图与麻数图
    PHP极客水平测试——给创业公司用的远程面试题
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/9890460.html
Copyright © 2020-2023  润新知