学习了解CyclicBarrier

CyclicBarrier我的理解就是一个线程等待器,用途就是将注册了这个barrier的线程卡在同一个位置,直到注册这个barrier的所有线程都完成之后,继续执行。
下面是一个学习过程中采用的示例,计算每个学生分别的成绩,然后统一汇总计算全班成绩
package cyclic;

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

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        List<String> students = Arrays.asList("Tom","Bill","Dick","Marry","Lily","Harry");
        StudentCalc calc = new StudentCalc();
        CyclicBarrier cyclicBarrier = new CyclicBarrier(students.size(),new TotalScore(calc));//所有注册cyclicBarrier的线程完成后才会执行TotalScore线程
        students.forEach(x-> new Thread(new StudentScore(cyclicBarrier,calc,x)).start());
        System.out.println("我在主线程");//对后续无影响
    }
}

class TotalScore implements Runnable{
    private StudentCalc studentCalc;

    TotalScore(StudentCalc studentCalc) {
        this.studentCalc = studentCalc;
    }


    @Override
    public void run() {
        studentCalc.total();//总成绩 计算
    }
}


class StudentScore implements Runnable{

    private CyclicBarrier barrier;
    private StudentCalc studentCalc;
    private String studentName;

    public StudentScore(CyclicBarrier barrier, StudentCalc studentCalc, String studentName) {
        this.barrier = barrier;
        this.studentCalc = studentCalc;
        this.studentName = studentName;
    }

    @Override
    public void run() {
        studentCalc.student(studentName);
        
        try {
            this.barrier.await();//计算完成后等待其他线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 计算类
 */
class StudentCalc {
    /**
     * 全部成绩计算完成后,调用汇总
     */
    public void total(){
        System.out.println("全体学生成绩汇总计算");

    }

    /**
     * 计算每个学生自己成绩,为了模拟每个学生计算时间不同,使用Thread.sleep区分
     * @param student
     */
    public void student(String student){
        try {
            Thread.sleep(new Random().nextInt(2000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("计算" + student + "成绩");
    }
}

  示例很简单,具体CyclicBarrier是如何实现的,后面在慢慢研究。

输出结果不固定如下所示:

我在主线程
计算Lily成绩
计算Bill成绩
计算Tom成绩
计算Dick成绩
计算Marry成绩
计算Harry成绩
全体学生成绩汇总计算

 

posted @ 2018-03-03 11:21  EvilTuzki  阅读(169)  评论(0编辑  收藏  举报