Java-多线程

CyclicBarrier 实现阶段性同步

2020-04-15  本文已影响0人  PageThinker

01 CyclicBarrier

01.png

CyclicBarrier 提供了如下功能:

(1)向上增加计数的功能

(2)阻塞等待功能

(3)阶段性同步功能(线程数大于 parties 数量时)

(4)支持多次循环实现多个线程一起执行的目的。


02 与 CountDownLatch 的比较

(1)CountDownLatch 时计数器做减法,而 CyclicBarrier 时通过累加来实现。

(2)CountDownLatch 只支持单次多个线程阻塞然后一起执行,CyclicBarrier 是支持多次的。


03 常用方法

await() 阻塞等待,直到达到构造函数中指定的数量之后继续向下执行。

getNumberWaiting() 获取有几个线程已到了阻塞节点

isBroken() 查询阻塞是否受到损坏,这里的损坏指的是当出现异常后 阻塞节点是否还能够正常工作。

例如: 5 个线程线程阻塞时有一个线程抛出了 NullPointException,那么只有抛出 NullPointException 的线程停止运行,其他 4 个线程依然在运行。

再比如:5 个线程中有一个线程执行了 interruput() 中断,那么其他几个阻塞等待的线程都会停止运行。阻塞节点被破坏。

getParties() 获取构造函数中指定的 parties 数

reset() 重置阻塞。


04 案例

10 个运动员(Runner)参加淘汰赛,两两一组比赛。

Runner.java

package com.page.concurrent.cyclicbarrier;

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

public class Runner extends Thread {
    private final CyclicBarrier cyclicBarrier;
    private final int number;

    public Runner(CyclicBarrier cyclicBarrier, int number) {
        this.cyclicBarrier = cyclicBarrier;
        this.number = number;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()
                + ":"
                + System.currentTimeMillis()
                + " Ready. Waiting another one.");


        try {
            Thread.sleep(1000 * number);
            cyclicBarrier.await();

            System.out.println(Thread.currentThread().getName() + " run.");
        } catch (InterruptedException e) {
            System.out.println("had exception when waiting others. e=" + e.getMessage());
        } catch (BrokenBarrierException e) {
            System.out.println("had exception when waiting others. e" + e.getMessage());
        }


    }
}

Game.java

package com.page.concurrent.cyclicbarrier;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;

public class Game {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2,
                () -> System.out.println(System.currentTimeMillis() + ">>>> 2 runner had ready."));
        List<Runner> runners = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            Runner runner = new Runner(cyclicBarrier, i);
            runner.start();
            runners.add(runner);
        }


    }
}

02.png
上一篇 下一篇

猜你喜欢

热点阅读