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();
                }
            }
        }
    
    }
  • 相关阅读:
    mysql如何查询最新插入的数据
    nodejs express开发
    在线考试实现倒计时的代码
    centos的vsftp修改上传下载速度
    centos vsftpd
    ul和li里面的list-style
    算法竞赛入门经典 暴力求解法 7.1简单枚举 最大乘积
    算法竞赛入门经典 暴力求解法 7.1简单枚举 最大乘积
    算法竞赛入门经典 暴力求解法 7.1简单枚举 除法
    算法竞赛入门经典 暴力求解法 7.1简单枚举 除法
  • 原文地址:https://www.cnblogs.com/alsf/p/9131453.html
Copyright © 2011-2022 走看看