CyclicBarrier

2.CyclicBarrier

  CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
  当一个线程到达集合点时,它将调用await()方法等待其它的线程。线程调用await()方法后,CyclicBarrier将阻塞这个线程,并将它置入休眠状态等待其它线程的到来。等最后一个线程调用await()方法时,CyclicBarrier将唤醒所有等待的线程,然后这些线程将继续执行。CyclicBarrier可以传入另一个Runnable对象作为初始化参数。当所有的线程都到达集合点后,CyclicBarrier类将Runnable对象作为线程执行。

方法

await():使线程置入休眠直到最后一个线程的到来之后唤醒所有休眠的线程

 

CyclicBarrier类有两个常用的构造方法:

1)CyclicBarrier(int parties)

这里的parties也是一个计数器,例如,初始化时parties里的计数是3,于是拥有该CyclicBarrier对象的线程当parties的计数为3时就唤醒,注意:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值。

2)CyclicBarrier(int parties, Runnable barrierAction)

这里的parties与上一个构造方法的解释是一样的,这里需要解释的是第二个入参(Runnable barrierAction),这个参数是一个实现Runnable接口的类的对象,也就是说当parties加到初始值时就触发barrierAction的内容。

   案例场景:有4个游戏玩家玩游戏,游戏有三个关卡,每个关卡必须要所有玩家都到达后才能允许通过。其实这个场景里的玩家中如果有玩家A先到了关卡1,他必须等到其他所有玩家都到达关卡1时才能通过,也就是说线程之间需要相互等待。这和CountDownLatch的应用场景有区别,CountDownLatch里的线程是到了运行的目标后继续干自己的其他事情,而这里的线程需要等待其他线程后才能继续完成后面的工作。   

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

package com.itszt.test3;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

/**

 * 测试CyclicBarrier

 */

public class CyclicBarrierTest {

    public static void main(String[] args) {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(4,

                new Runnable() {

                    @Override

                    public void run() {

                        System.out.println("所有玩家进入第 2 关!");

                    }

                });

        for (int i = 1; i <= 4; i++) {

            new Thread(new Player(i, cyclicBarrier)).start();

        }

    }

}

 

/**

 * 玩家类

 *

 * @author itmyhome

 */

class Player implements Runnable {

    private CyclicBarrier cyclicBarrier;

    private int id;

 

    public Player(int id, CyclicBarrier cyclicBarrier) {

        this.cyclicBarrier = cyclicBarrier;

        this.id = id;

    }

 

    @Override

    public void run() {

        try {

            System.out.println("玩家" + id + "正在玩第 1 关...");

            cyclicBarrier.await();

            System.out.println("玩家" + id + "进入第 2 关...");

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (BrokenBarrierException e) {

            e.printStackTrace();

        }

    }

}

   代码执行结果如下:

玩家1正在玩第 1 关...

玩家3正在玩第 1 关...

玩家2正在玩第 1 关...

玩家4正在玩第 1 关...

所有玩家进入第 2 关!

玩家4进入第 2 关...

玩家1进入第 2 关...

玩家3进入第 2 关...

玩家2进入第 2 关...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值