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();
                }
            }
        }
    
    }
  • 相关阅读:
    文件上传时jquery.form.js中提示form.submit SCRIPT5: 拒绝访问
    window.open参数设置及如何全屏显示(转)
    使用jQuery清空file文件域的解决方案(转)
    Aspose.Cells 设置背景颜色
    sql查询指定范围内的所有月份
    sql查询当前月内的所有日期
    浏览器打印显示页眉页脚
    保留两位小数正则
    Windows Server 2008 R2 域控服务器运行nslookup命令默认服务器显示 UnKnown
    Windows Server 2008 R2 主域控制器委派DNS到子域控控制器
  • 原文地址:https://www.cnblogs.com/alsf/p/9131453.html
Copyright © 2011-2022 走看看