MST
星途 面试题库

面试题:Java中Barrier实现原理剖析

以CyclicBarrier为例,深入分析其内部实现原理,包括如何实现线程等待与唤醒机制,以及它与其他同步工具如Semaphore在原理上的异同点。
19.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

CyclicBarrier内部实现原理

  1. 线程等待机制
    • CyclicBarrier内部维护了一个计数器parties,表示需要等待的线程数量。当每个线程调用await()方法时,计数器会减1。
    • 当计数器的值不为0时,调用await()的线程会调用Conditionawait()方法进入等待状态。Condition是基于ReentrantLock实现的,ReentrantLock提供了线程同步的基础。
    • 例如,假设有3个线程调用await(),前两个线程调用await()后,计数器变为1和0,这两个线程会进入等待状态。
  2. 唤醒机制
    • 当计数器减到0时,表示所有线程都已到达屏障点。此时,CyclicBarrier会调用ConditionsignalAll()方法,唤醒所有等待在该Condition上的线程。
    • 被唤醒的线程从await()方法中返回,继续执行后续的代码。同时,CyclicBarrier会将计数器重置为初始值parties,以便下一轮使用,这也是它“Cyclic”(可循环)特性的体现。

与Semaphore原理上的异同点

  1. 相同点
    • 线程同步:两者都用于线程同步,控制线程的并发执行,以避免竞争条件和确保程序的正确性。
    • 基于锁机制:底层都依赖锁机制来实现线程的同步。Semaphore基于AQS(AbstractQueuedSynchronizer)实现,CyclicBarrier内部的ReentrantLock也是基于AQS实现,AQS为它们提供了线程排队、等待和唤醒等基础功能。
  2. 不同点
    • 功能目的
      • CyclicBarrier:主要用于让一组线程相互等待,直到所有线程都到达某个屏障点,然后一起继续执行。常用于多线程协作完成某个任务阶段,然后一起进入下一阶段的场景。
      • Semaphore:用于控制同时访问某个资源的线程数量,通过信号量的获取和释放来限制并发访问。常用于限制对共享资源的并发访问,如数据库连接池的连接数量控制。
    • 资源模型
      • CyclicBarrier:不涉及资源的概念,它关注的是线程组的同步。
      • Semaphore:维护了一个虚拟的资源池,信号量的数量代表了可用资源的数量。
    • 可重用性
      • CyclicBarrier:具有可循环使用的特性,计数器重置后可以再次使用。
      • Semaphore:信号量的数量是固定的,获取和释放操作改变的是可用信号量的数量,不会重置为初始状态(除非手动重新设置)。