java多线程CyclicBarrier和CountDownLatch的使用,同步等待多个线程都执行完后,再执行后面的操作

Java的CountDownLatch和CyclicBarrier的理解和区别
CountDown表示减法计数,Latch表示门闩的意思,计数为0的时候就可以打开门闩了。
Cyclic Barrier表示循环的障碍物。
两个类都含有这一个意思:对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步。然而两者最大的区别是,进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。

对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;
对于CyclicBarrier,下一步动作实施者是“其他线程”。

CountDownLatch

package com.uwanyi.lottery_draw;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        //如果想要返回结果,则将每个线程放入集合中
        List<MyThread> myThreadList = new ArrayList<>();
        //英雄联盟5v5 所有玩家都准备就绪后才开始游戏
        CountDownLatch latch = new CountDownLatch(5);
        for(int i = 0; i < latch.getCount(); i++){
            MyThread myThread = new MyThread(latch);
            new Thread(myThread, "player"+i).start();
            myThreadList.add(myThread);//放入集合
        }
        System.out.println("正在等待所有玩家准备好");
        latch.await();
        //获取线程结果
        for(MyThread myThread:myThreadList){
        	//此处可根据需要做其他处理
            System.out.println(myThread.getTotal());
        }
        System.out.println("开始游戏");
    }
    private static class MyThread implements Runnable{
        private CountDownLatch latch ;
        private String result;
        public MyThread(CountDownLatch latch){
            this.latch = latch;
        }
        @Override
        public void run() {
            try {
                Random rand = new Random();
                int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数

                Thread.sleep(randomNum);
                System.out.println(Thread.currentThread().getName()+" 已经准备好了, 所使用的时间为 "+((double)randomNum/1000)+"s");
                result = Thread.currentThread().getName() + ":" + randomNum;
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public String getTotal(){
            return result;
        }
    }
}

CyclicBarrier

package com.uwanyi.lottery_draw;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
    public static void main(String[] args) {
        //5名队友,通过3个关卡。每到一个关卡需要等待5人都到达再进行下一个关卡
        CyclicBarrier barrier = new CyclicBarrier(5);
        for(int i = 0; i < barrier.getParties(); i++){
            new Thread(new MyRunnable(barrier), "队友"+i).start();
        }
        System.out.println("main function is finished.");
    }
    private static class MyRunnable implements Runnable{
        private CyclicBarrier barrier;
        public MyRunnable(CyclicBarrier barrier){
            this.barrier = barrier;
        }
        @Override
        public void run() {
            //3个关卡
            for(int i = 0; i < 3; i++) {
                try {
                    String theadName = Thread.currentThread().getName();
                    Random rand = new Random();
                    int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数
                    Thread.sleep(randomNum);
                    System.out.println(theadName + ", 通过了第"+i+"个障碍物, 使用了 "+((double)randomNum/1000)+"s");
                    //此处是关键,每个线程队友到达此处,会进行等待检查是否已有5名队友到达(包含自己),如果达到规定的5个,则进行下一步
                    this.barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值