24.循环栅栏 CyclicBarrier

Posted fly-book

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了24.循环栅栏 CyclicBarrier相关的知识,希望对你有一定的参考价值。

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

/**
 * 循环栅栏 CyclicBarrier
 * 可以反复使用的计数器
 * 如:计数器设置为10,凑齐第一批10个线程后,计数器就会归零,然后接着凑齐下一批10个线程
 *
 *  public CyclicBarrier(int parties, Runnable barrierAction) //计数总数,线程总数
 */
public class CyclicBarrierDemo 
    public static class Soldier implements Runnable
        private String soldier;
        private final CyclicBarrier cyclicBarrier;
        Soldier(String soldierName, CyclicBarrier cyclicBarrier) 
            this.soldier = soldierName;
            this.cyclicBarrier = cyclicBarrier;
        
        @Override
        public void run() 
            try 
                //等待任务安排
                System.out.println("开始了");
                cyclicBarrier.await();
                doWork();
                //等待任务完成
                cyclicBarrier.await();
             catch (InterruptedException | BrokenBarrierException e) 
                //InterruptedException线程被中断
                //BrokenBarrierException:表示当前的cyclicBarrier已经破损了,避免其他线程进行永久的,无所谓的等待
                e.printStackTrace();
            
        

        void doWork() 
            try 
                Thread.sleep(Math.abs(new Random().nextInt()%10000));
             catch (InterruptedException e) 
                e.printStackTrace();
            
            System.out.println(soldier+":任务完成");
        
    
    public static class BarrierRun implements Runnable
        boolean  flag;
        int N;

        public BarrierRun(boolean flag, int n) 
            this.flag = flag;
            N = n;
        

        @Override
        public void run() 
            if (flag)
                System.out.println(N+"个任务已完成!");
            else 
                System.out.println("安排"+N+"个任务!");
                flag = true;
            
        
    
    public static void main(String[] args)
        final int N = 10;
        Thread[] allSoldier = new Thread[10];
        boolean flag = false;
        CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
        System.out.println("安排任务...");
        for (int i = 0; i < N; i++) 
            System.out.println("任务"+i+"安排");
            allSoldier[i] = new Thread(new Soldier("任务"+i,cyclic));
            allSoldier[i].start();
        
    
    //每运行完N个次数的任务就会执行BarrierRun任务

    //安排任务...
    //任务0安排
    //任务1安排
    //开始了
    //开始了
    //任务2安排
    //开始了
    //任务3安排
    //开始了
    //任务4安排
    //任务5安排
    //开始了
    //任务6安排
    //开始了
    //任务7安排
    //开始了
    //任务8安排
    //开始了
    //开始了
    //任务9安排
    //开始了
    //安排10个任务!
    //任务6:任务完成
    //任务3:任务完成
    //任务9:任务完成
    //任务5:任务完成
    //任务4:任务完成
    //任务0:任务完成
    //任务8:任务完成
    //任务7:任务完成
    //任务2:任务完成
    //任务1:任务完成
    //10个任务已完成!

以上是关于24.循环栅栏 CyclicBarrier的主要内容,如果未能解决你的问题,请参考以下文章

循环栅栏:CyclicBarrier(司令要求任务) 读书笔记

JAVA并发包源码分析循环栅栏:CyclicBarrier

同步工具类-----循环栅栏:CyclicBarrier

是否应该为互斥锁获取-交换循环(或队列获取-加载循环)组合内存栅栏,还是应该避免?

源码分析:CyclicBarrier 之循环栅栏

多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier