zoukankan      html  css  js  c++  java
  • JUC-闭锁:CountDownLatch

    CountDownLatch::闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行。

    实例化:参数:设置一个计数器的值。

    final CountDownLatch latch = new CountDownLatch(5);

    计数器减一:

    latch.countDown();

    计数器等待:

    latch.await();

    效果:首先初始化一个CountDownLatch对象,该对象设置计数器的值,在需要运算的地方,每次执行完一次运输,通过latch.countDown()方法来执行减一,

    等到latch的初始化值减为0的时候,latch后面的代码才能执行。

    例如:有5个线程,每个线程都有一些运算,需要计算5个线程全部执行完了后,花了多长时间。

    假如不使用countDownLatch,直接在线程前后加上时间记录。

    package com.atguigu.juc;
    
    import java.util.concurrent.CountDownLatch;
    
    /*
     * CountDownLatch :闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行
     */
    public class TestCountDownLatch {
    
        public static void main(String[] args) {
    
            LatchDemo ld = new LatchDemo();
    
            long start = System.currentTimeMillis();
    
            for (int i = 0; i < 5; i++) {
                new Thread(ld).start();
            }
    
            long end = System.currentTimeMillis();
            System.out.println("耗费时间为:" + (end - start));
        }
    }
    
    class LatchDemo implements Runnable {
    
        @Override
        public void run() {
            
            synchronized (this) {
                    for (int i = 0; i < 50000; i++) {
                        if (i % 2 == 0) {
                            System.out.println(i);
                        }
                    }
            }
        }
    
    }

    这样计算的结果是有问题的,因为主线程本身是一个线程,即使循环里面的线程没有执行完依然会执行后面的:此时得到的结果是不准确的

            long end = System.currentTimeMillis();
            System.out.println("耗费时间为:" + (end - start));

    要想所有线程都执行完了才计算结果,使用countDownLatch,通过计数器,闭锁。

    使用CountDownLatch后的代码:

    package com.atguigu.juc;
    import java.util.concurrent.CountDownLatch;
    
    /*
     * CountDownLatch :闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行
     */
    public class TestCountDownLatch {
    
        public static void main(String[] args) {
            final CountDownLatch latch = new CountDownLatch(5);
            LatchDemo ld = new LatchDemo(latch);
    
            long start = System.currentTimeMillis();
    
            for (int i = 0; i < 5; i++) {
                new Thread(ld).start();
            }
    
            try {
                //只有当计数器的指为0的时候,这里才能执行下面的话
                latch.await();
            } catch (InterruptedException e) {
            }
    
            long end = System.currentTimeMillis();
            System.out.println("耗费时间为:" + (end - start));
        }
    }
    
    class LatchDemo implements Runnable {
    
        private CountDownLatch latch;
    
        public LatchDemo(CountDownLatch latch) {
            this.latch = latch;
        }
    
        @Override
        public void run() {
            
            synchronized (latch) {
                try {
                    for (int i = 0; i < 50000; i++) {
                        if (i % 2 == 0) {
                            System.out.println(i);
                        }
                    }
                } finally {
                    //每次执行完,该计数器减一
                    latch.countDown();
                }
            }
        }
    
    }
  • 相关阅读:
    google protobuf ios开发使用
    iOS下载使用系统字体
    xcode7 打开工程错误 This Document requires xcode8.0 or later.
    mac 文本编辑器 文本编码Unicode utf-8 不适用的问题
    iOS中JS 与OC的交互(JavaScriptCore.framework)
    cookie 设置报错 setcookie() expects parameter 3 to be integer, float given in...
    wordpress 获取指定作者或者文章的所有评论数量
    HTML a标签链接 设置点击下载文件
    PHPUnit 单元测试教程
    phpstudy 首次安装后打开网站 数据库内容 中文乱码
  • 原文地址:https://www.cnblogs.com/alsf/p/9131453.html
Copyright © 2011-2022 走看看