2.2线程的并发工具类-CountDownLatch、CyclicBarrier

一、CountDownLatch

1、作用

一组线程等待其他线程完成工作之后再执行,比较像加强版的join
下面演示下用法,5个线程6个扣除点,等待5个线程工作完成后,业务线程才进行自己的逻辑处理。

package cn.enjoy.controller.thread.CountDownLatch;

import cn.enjoy.controller.thread.DBPOLL.SleepTools;

import java.util.concurrent.CountDownLatch;

/**
 * @ author:wangle
 * @ description: countDownLatch的使用,6个初始化线程,6个扣除点,等待处理完之后业务线程和主线程才能进行处理自己的模块
 * @ version:V1.0
 * @ date:2020-03-21 20:52
 **/
public class UseCountDownLatch {

    static CountDownLatch latch = new CountDownLatch(6);

    //初始化线程
    private static class InitThread implements Runnable{
        @Override
        public void run(){
            System.out.println("Thread:"+Thread.currentThread().getName()+"初始化工作");
            latch.countDown();
            //TODO 还可以继续做其他业务
        }
    }

    //业务线程,扣除1次
    private static class BusinessThread implements Runnable{
        @Override
        public void run(){
            try{
                latch.await();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Thread:"+Thread.currentThread().getName()+"业务线程执行了");
        }
    }


    //业务线程,扣除2次
    private static class BusinessThread2 extends Thread{

        @Override
        public void run(){
            SleepTools.ms(1);
            System.out.println("Thread:"+Thread.currentThread().getName()+"初始化工作1");
            latch.countDown();
            SleepTools.ms(1);
            System.out.println("Thread:"+Thread.currentThread().getName()+"初始化工作2");
            latch.countDown();
        }
    }



    public static void main(String[] args)throws InterruptedException{

        //业务线程开始执行
        new Thread(new BusinessThread()).start();

        //初始化线程执行
        for(int i=0;i<4;i++){
            Thread thread = new Thread(new InitThread());
            thread.start();
        }
        
        Thread thread = new BusinessThread2();
        thread.start();
        
        latch.await();
        System.out.println("主线程在执行了");
    }
}

在这里插入图片描述
看到,当5个线程扣除6次之后,主线程和业务线程才开始执行,因为主线程和业务线程执行了await操作,在等待初始化线程扣除操作完成。

二、CyclicBarrier

1、作用

一组线程到达了某个屏障,当这组线程全部到达了屏障点后全部线程才继续向下执行

package cn.enjoy.controller.thread.UseCyclicBarrier;

import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;

/**
 * @author:wangle
 * @description:使用CyclicBarrier
 * @version:V1.0
 * @date:2020-03-21 21:28
 **/
public class UseCyclicBarrier {

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,new BusinessThread());
    private static HashMap<String,Long> threadIdMap = new HashMap<>();

    private static class WorkThread extends Thread{
        @Override
        public void run(){
            long id = Thread.currentThread().getId();
            threadIdMap.put(Thread.currentThread().getId()+"",id);
            Random r = new Random();
            try{
                if(r.nextBoolean()){
                    Thread.sleep(2000);
                    System.out.println("Thread_"+id+"还没到await,在做其他事情");
                }
                System.out.println("Thread_"+id+"在await");
                cyclicBarrier.await();
                System.out.println("Thread_"+id+"业务代码执行");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private static class BusinessThread extends Thread{
        @Override
        public void run(){
            System.out.println(threadIdMap);
        }
    }

    public static void main(String[] args){
        for(int i=0;i<5;i++){
            Thread thread = new WorkThread();
            thread.start();
        }
    }


}

在这里插入图片描述
可以看到,线程12,11很快到达了await,但是14,13,15还没有到达await,,此时12,11并没有进行继续操作,而是等待剩余的线程全部到达await之后才进行await之后的逻辑处理。有兴趣的小伙伴可以执行下程序,明显的感受下程序堵塞等待的顺序。

CyclicBarrier还接收了一个线程的参数,这个线程也是当所有线程都到达了屏障之后才进行继续操作。这个参数可有可无,根据自己的程序需要进行传递。

三、CountDownLatch和cyclicBarrier辨析

1、CountDownLatch放行由外部线程决定,cyclicBarrier放行是由一组线程本身决定的
2、CountDownLatch的放行条件执行数大于等于线程数、cyclicBarrier的放行条件执行数等于线程数量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值