← Concepts

阅读中文版本

Barrier Synchronization

A barrier is a synchronization point at which every participant must arrive before any proceeds, used to separate phases of a parallel computation so no phase reads half-written state from the next.

concurrency

Definition

Barrier synchronization is a coordination primitive where a set of threads or processes all wait at a barrier until every participant has arrived, then all are released together, so that the computation proceeds in phases and no phase begins until the previous phase is fully complete across all workers.

Context and scope

Applied in bulk synchronous parallel processing, phased map-reduce, scientific simulation, and any parallel computation with a clear phase boundary.

Common misconceptions

  • A barrier is just a join — a join waits for completion; a barrier is reusable across phases, a join is one-shot
  • Barriers eliminate the need for locks — they eliminate locks between phases; within a phase, shared state still needs protection

Anti-patterns

  • Using a barrier between phases that have no data dependency, serializing phases that could overlap and reducing parallelism
  • Forgetting to reset a reusable barrier, so the second phase releases immediately without waiting

Related concepts

Authoritative source

https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CyclicBarrier.html

What it is

Barrier synchronization is a coordination primitive where a set of threads or processes all wait at a barrier until every participant has arrived, then all are released together, so that the computation proceeds in phases and no phase begins until the previous phase is fully complete across all workers. Applied in bulk synchronous parallel processing, phased map-reduce, scientific simulation, and any parallel computation with a clear phase boundary. The central difficulty is that interleaving is nondeterministic: the set of possible executions grows super-exponentially with the number of operations, and testing samples a vanishing fraction.

How it works

Correctness is established by reasoning about happens-before relationships, not by running more tests. Synchronization primitives are chosen for the specific guarantee needed — mutual exclusion, publication, or ordering — and composed only with a documented proof of absence of deadlock. Bounded resources apply backpressure rather than unbounded queuing that hides overload until memory exhausts.

When to apply and pitfalls

Apply whenever multiple flows share mutable state or resources. The dominant pitfall is reasoning sequentially about concurrent code — “this can’t happen because A finishes before B” — when in fact the scheduler can interleave at any instruction boundary. The second is using a coarse lock for simplicity and turning parallelism back into serialization.