掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

并发同步工具CyclicBarrier详解(概念、原理、作用、用法)

在Java并发编程中,如何高效地协调多个线程的执行是一个常见且复杂的问题。本文将详细介绍Java并发包中的CyclicBarrier工具类,探讨它的概念、原理、作用及用法。无论你是初学者还是有经验的开发者,通过这篇文章,你将对CyclicBarrier有更深入的理解,并能在实际项目中灵活运用。

一、CyclicBarrier概念

CyclicBarrier译为“循环栅栏”,是Java提供的一种同步辅助类,允许一组线程互相等待,直到所有线程都到达某个公共的屏障点(Barrier Point)后再同时继续执行。这种机制确保了所有参与的线程能够在某个共同点上同步,避免出现某些线程提前进入下一步操作的情况。

主要特点

  1. 多线程等待与协同:使一组线程可以在某一点上同步。

  2. 循环使用:与CountDownLatch不同,CyclicBarrier可以重置后重复使用。

  3. 可选的屏障动作:在所有线程到达屏障时,可以选择执行一段特定的代码逻辑。

二、工作原理

CyclicBarrier内部通过计数器来实现其功能。以下是其工作流程的详细说明:

  1. 初始化

创建一个CyclicBarrier对象时,需要指定参与同步的线程数量(parties数量)。这个数量决定了有多少个线程必须到达屏障点,才能继续执行后续操作。

int parties = 3;
CyclicBarrier barrier = new CyclicBarrier(parties);
  1. 等待屏障

当一个线程调用CyclicBarrier的await()方法时,该线程将被阻塞,直至所有指定的线程都到达屏障点。每当一个线程到达屏障点时,计数器减1。

barrier.await(); // 当前线程将在此处等待其他线程
  1. 唤醒线程

当最后一个线程到达屏障点时,计数器归零,所有被阻塞的线程将被唤醒,并从await()方法返回,然后同时继续执行后续的代码。

  1. 可选的屏障动作

可以在CyclicBarrier构造函数中传入一个Runnable对象,表示所有线程到达屏障点时要执行的任务。这个Runnable对象在所有线程都被唤醒之前执行。

CyclicBarrier barrier = new CyclicBarrier(parties, new Runnable()out.println("All threads have reached the barrier");
    }
});
  1. 异常处理

如果在等待期间,某个线程发生中断或抛出异常,所有被阻塞的线程都将收到一个BrokenBarrierException异常。这可以防止因个别线程的问题而导致整个系统的死锁或不一致状态。

三、CyclicBarrier的作用

CyclicBarrier的主要作用是让一组线程在某个点上相互等待,直到所有线程都准备好后一起继续执行。这种机制特别适用于需要分阶段执行的任务,每个阶段都需要所有线程完成各自的工作后才能进入下一个阶段。例如,在一个并行计算任务中,可以将整个计算过程分为多个阶段,每个阶段结束后使用CyclicBarrier确保所有线程都完成当前阶段的工作,然后再一起进入下一个阶段。

四、使用方法和示例

  1. 基本用法

下面是一个简单的示例,展示了如何使用CyclicBarrier来同步三个线程:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; i < PARTIES; i++) {
            new Thread(new Worker(i)).start();
        }
    }
    static class Worker implements Runnable {
        private final int threadNum;
        Worker(int threadNum) {
            this.out.println("Thread " + threadNum + " is waiting at the barrier.");
                barrier.await();
                System.out.println("Thread " + threadNum + " has passed the barrier.");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

输出示例:

Thread 0 is waiting at the barrier.
Thread 1 is waiting at the barrier.
Thread 2 is waiting at the barrier.
All threads have reached the barrier
Thread 0 has passed the barrier.
Thread 1 has passed the barrier.
Thread 2 has passed the barrier.

在这个示例中,三个线程分别在屏障点等待,当所有线程都到达后,打印出一条信息,然后继续执行。

  1. 带回调函数的使用

在实际应用中,你可能希望所有线程到达屏障点后执行一些特定的逻辑,例如数据汇总或资源释放。这时可以使用CyclicBarrier的第二个构造函数,传入一个Runnable作为回调函数。所有线程到达屏障后的回调逻辑

        System.out.println("All threads have reached the barrier, performing callback.");
    }
});
  1. 分治任务的并行计算

假设我们有一个大型任务需要并行处理,我们可以将任务分解为多个子任务,每个子任务由一个线程完成。当所有子任务完成后,再进行结果合并。这种情况下,CyclicBarrier显得尤为重要。例如:

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

public class ParallelTask {
    private static final int PARTIES = 3;
    private static final CyclicBarrier barrier = new CyclicBarrier(PARTIES, new Runnprintln("All subtasks completed, merging results... i < PARTIES; i++) {
            final int threadIndex = i;
            new Thread(() -> {
                try {
                    int result = doSubtask(threadIndex);
                    results.add(result);
                    barrier.await(); // 等待所有子任务完成
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
    private static int doSubtask(int index) {
        // 模拟子任务的处理时间
        try {
            Thread.sleep((long) (Math.random() * 1000));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("Subtask " + index + " completed with result: " + (index * index));
        return index * index;
    }
}

在这个例子中,我们将大任务分解为三个子任务,每个子任务由一个独立的线程完成。所有子任务完成后,通过CyclicBarrier的回调函数进行结果合并。这样可以确保所有子任务的结果都已准备好,然后再进行下一步操作。
CyclicBarrier是Java并发包提供的一种强大的同步工具,适用于需要在多个线程间进行协调的场景。其主要特点包括循环使用、多线程等待与协同以及可选的屏障动作。通过合理应用CyclicBarrier,可以大大简化多线程程序的复杂性,提高系统的稳定性和可靠性。

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • 全球天气预报

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

  • 购物小票识别

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

  • 涉农贷款地址识别

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

  • 人脸四要素

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

  • 个人/企业涉诉查询

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

0512-88869195
数 据 驱 动 未 来
Data Drives The Future