博客
关于我
JAVA同步屏障CyclicBarrier
阅读量:304 次
发布时间:2019-03-03

本文共 3988 字,大约阅读时间需要 13 分钟。

CyclicBarrier 是 Java 提供的一种同步工具,用于管理多线程程序中的屏障。它允许一组线程在到达屏障时被阻塞,直到最后一个线程到达屏障时,所有被屏障拦截的线程才会继续执行。

1. 简单介绍CyclicBarrier

1.1 功能说明

CyclicBarrier 可以让一组线程在到达屏障时被阻塞,直到最后一个线程到达屏障。所有被屏障拦截的线程只有在最后一个线程到达屏障后才会继续执行。这种机制在多线程计算数据时非常有用,例如计算结果完成后插入同步屏障,阻塞等待所有线程完成。

1.2 类的位置

CyclicBarrier 位于 Java 的 java.util.concurrent 包下。线程在执行 await() 方法后会到达屏障,并等待其他线程也到达屏障。

1.3 构造方法

CyclicBarrier 的构造方法主要有以下两种形式:

  • 传递拦截线程数的参数:
  • public CyclicBarrier(int parties) {    this(parties, null);}
    1. 传递拦截线程数的参数和一个执行的线程任务:
    2. public CyclicBarrier(int parties, Runnable barrierAction) {    if (parties <= 0) throw new IllegalArgumentException();    this.parties = parties;    this.count = parties;    this.barrierCommand = barrierAction;}

      2. 基础使用演示

      2.1 两个线程的示例

      以下是一个简单的两个线程示例,主线程和一个自定义的子线程都执行 await() 方法:

      import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest {    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);    public static void main(String[] args) {        new Thread(new Runnable() {            @Override            public void run() {                try {                    cyclicBarrier.await();                } catch (InterruptedException e) {                    e.printStackTrace();                } catch (BrokenBarrierException e) {                    e.printStackTrace();                }                System.out.println("Thread执行");            }        }).start();        try {            cyclicBarrier.await();        } catch (InterruptedException e) {            e.printStackTrace();        } catch (BrokenBarrierException e) {            e.printStackTrace();        }        System.out.println("Main执行");    }}

      2.2 执行结果

      由于 Java 多线程执行顺序由 CPU 随机调度决定,运行结果可能有以下两种情况:

    3. 主线程先于子线程到达屏障,子线程继续等待。
    4. 子线程先于主线程到达屏障,主线程继续等待。
    5. 3. 实战演练

      3.1 场景描述

      假设我们有一个 Excel 文件,保存了一个用户的多个银行账户的银行消费记录。每个工作表(Sheet)对应一个银行卡的消费流水记录。我们需要统计该用户一年内的平均每日银行消费金额。

      3.2 实现思路

      为了提高计算效率,使用多线程分别统计每个工作表的日均消费金额。所有线程完成后,通过 CyclicBarrier 同步,计算出所有账户的日均消费金额,最后得到该用户一年内的日均银行消费金额。

      3.3 可能出现的问题

    6. 如果使用单线程计算,数据量大可能导致效率低下。
    7. 如果不使用 CyclicBarrier,计算时需要等待所有工作表完成,操作不便且容易出错。
    8. 3.4 编码实现

      import java.util.Map;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.Executors;public class BankConsumeFlow implements Runnable {    private static final Integer CPU_NUMBER = Runtime.getRuntime().availableProcessors();    private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, this);    private ConcurrentHashMap
      sheetCount = new ConcurrentHashMap<>(); private void flowCount() { Executor executor = Executors.newFixedThreadPool(CPU_NUMBER); final CountDownLatch latch = new CountDownLatch(CPU_NUMBER); for (int i = 0; i < CPU_NUMBER; i++) { executor.execute(new Runnable() { @Override public void run() { try { int sheetName = Thread.currentThread().getName(); sheetCount.put(sheetName, 100); // 模拟一个工作表的日均流水 cyclicBarrier.await(); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } int result = 0; for (Map.Entry
      entry : sheetCount.entrySet()) { result += entry.getValue(); } sheetCount.put("result", result); System.out.println("该用户这一年的银行消费日均为:" + result + "元"); } public static void main(String[] args) { BankConsumeFlow bankConsumeFlow = new BankConsumeFlow(); bankConsumeFlow.flowCount(); }}

      4. 关键方法总结

      4.1 getParties()

      返回 CyclicBarrier 拦截的线程数目。

      4.2 getNumberWaiting()

      返回当前正在阻塞的线程数目(0 到 getParties() - 1)。

      4.3 await()

      线程到达屏障后等待其他线程到达屏障。

      4.4 reset()

      重置计算器,允许线程重新执行。

    转载地址:http://tvll.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现Diffie—Hellman密钥交换(附完整源码)
    查看>>
    Objective-C实现Dijkstra最小路径算法(附完整源码)
    查看>>
    Objective-C实现dijkstra迪杰斯特拉算法(附完整源码)
    查看>>
    Objective-C实现dijkstra迪杰斯特拉算法(附完整源码)
    查看>>
    Objective-C实现Dijkstra迪杰斯特拉算法(附完整源码)
    查看>>
    Objective-C实现dijkstra银行家算法(附完整源码)
    查看>>
    Objective-C实现Dinic算法(附完整源码)
    查看>>
    Objective-C实现disjoint set不相交集算法(附完整源码)
    查看>>
    Objective-C实现DisjointSet并查集的算法(附完整源码)
    查看>>
    Objective-C实现djb2哈希算法(附完整源码)
    查看>>
    Objective-C实现DNF排序算法(附完整源码)
    查看>>
    Objective-C实现doomsday末日算法(附完整源码)
    查看>>
    Objective-C实现double factorial iterative双阶乘迭代算法(附完整源码)
    查看>>
    Objective-C实现double factorial recursive双阶乘递归算法(附完整源码)
    查看>>
    Objective-C实现double hash双哈希算法(附完整源码)
    查看>>
    Objective-C实现double linear search recursion双线性搜索递归算法(附完整源码)
    查看>>
    Objective-C实现double linear search 双线性搜索算法(附完整源码)
    查看>>
    Objective-C实现double sort双重排序算法(附完整源码)
    查看>>
    Objective-C实现DoublyLinkedList双链表的算法(附完整源码)
    查看>>
    Objective-C实现DoublyLinkedList双链表算法(附完整源码)
    查看>>