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();
            }
        }
    }

}

猜你喜欢

转载自www.cnblogs.com/alsf/p/9131453.html