并发工具类 : CountDownLatch

CountDownLatch

一、作用

  • CountDownLatchTest是并发编程的工具类,当一个线程需要等待其他一组线程完毕后再执行,就可以使用CountDownLatch,
    当线程只需要等待其他一个线程的时候我们一般会使用join,CountDownLatch有点像一个加强版的join。
    比如我们有四个线程同时对某个数据源进行分析,我们需要在四个线程执行完后,主线程将分析结果保存到数据库,就可以借助CountDownLatch来实现

二、代码

 package com.intellif.mozping.concurrentutil.countdownLatchp;

import com.intellif.mozping.tools.SleepTools;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author by mozping
 * @Classname CountDownLatchTest
 * @Description CountDownLatch测试类
 * 初始化了CountDownLatch类,初始化若干个扣除点,比如5个,
 * 在主线程中初始化5个业务线程,每个业务线程执行完成后,减去一个扣除点,主线程会等待扣除点为0后才执行,
 * 这里每次默认扣除一个扣除点,注意如果初始化了6个扣除点,五个线程只扣除5次,那么主线程就会一直阻塞住
 * @Date 2019/1/2 15:51
 */
public class CountDownLatchTest {

    private static CountDownLatch countDownLatch = new CountDownLatch(5);

    /**
     * 主线程
     */
    public static void main(String[] args) throws InterruptedException {

        for (int i = 1; i <= 5; i++) {
            new MyBussinessThread().start();
        }

        //主线程等待
        countDownLatch.await(15, TimeUnit.SECONDS);
        System.out.println("主线程等待结束后执行...,剩余扣除点:" + countDownLatch.getCount());


    }

    /**
     * 业务线程
     */
    private static class MyBussinessThread extends Thread {
        @Override
        public void run() {
            System.out.println("业务线程 [" + Thread.currentThread().getName() + "] 处理业务...");
            //随机休眠10以内的时间
            SleepTools.randomSecond(10);
            System.out.println("业务线程 [" + Thread.currentThread().getName() + "] 处理业务完毕...");
            //完成后扣减一次
            countDownLatch.countDown();
        }
    }
}

三、注意事项

  • 这里每个线程执行完毕后会扣除一个扣除点,默认线程数量是5,扣除点可以大于或者等于5,比如根据业务场景,部分线程执行后又多个扣除点,如果线程执行完毕后扣除点没有归零,那么主线程就会阻塞。

四、Tips

  • countDownLatch.getCount()可以获取到剩余的扣除数
  • await方法可以指定超时时间,避免程序阻塞一直不往下执行
  • 注意在创建的子线程中执行任务之后,对CountDownLatch进行扣减,之前在一次代码中,子线程里面有一个while循环,不小心把扣减写到了循环体里面,结果主线程根本无法等到所有的子线程执行完毕,就扣减完了,导致结果不对,后面要注意这点

你可能感兴趣的:(并发编程)