Record arrivals counted down against a latch and report whether the barrier released.

countdown latch A coordination report can record progress toward a barrier. An `java.util.concurrent.atomic.AtomicInteger` started at a fixed count models a countdown latch, and each `decrementAndGet` records one arrival while `get` reports how many arrivals are still missing. With no arrivals the latch is still waiting, with some arrivals it is partial, and once the count reaches zero the barrier is released. The status line summarizes whether the latch stayed waiting, partial, or released after the recorded arrivals.

Countdown Latch Coordination Report

arrivals
CountdownLatchCoordinationReport.kt
Replay: real traced execution (multi-file project)
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val arrivals = 2
    val needed = 3
    val latch = AtomicInteger(needed)
    var counted = 0

    for (i in 0 until arrivals) {
        latch.decrementAndGet()
        counted++
    }

    val remaining = latch.get()
    val released = remaining == 0

    val status = if (counted == 0) {
        "waiting"
    } else if (released) {
        "released"
    } else {
        "partial"
    }

    println("arrivals=$arrivals counted=$counted remaining=$remaining $status")
}
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val arrivals = 0
    val needed = 3
    val latch = AtomicInteger(needed)
    var counted = 0

    for (i in 0 until arrivals) {
        latch.decrementAndGet()
        counted++
    }

    val remaining = latch.get()
    val released = remaining == 0

    val status = if (counted == 0) {
        "waiting"
    } else if (released) {
        "released"
    } else {
        "partial"
    }

    println("arrivals=$arrivals counted=$counted remaining=$remaining $status")
}
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val arrivals = 3
    val needed = 3
    val latch = AtomicInteger(needed)
    var counted = 0

    for (i in 0 until arrivals) {
        latch.decrementAndGet()
        counted++
    }

    val remaining = latch.get()
    val released = remaining == 0

    val status = if (counted == 0) {
        "waiting"
    } else if (released) {
        "released"
    } else {
        "partial"
    }

    println("arrivals=$arrivals counted=$counted remaining=$remaining $status")
}
  1. arrivals ← 2, needed ← 3, latch ← 3, counted ← 0

    3fun main() {4    val arrivals→ 2 = 2 //@arrivals=0, 35    val needed→ 3 = 36    val latch→ 3 = AtomicInteger(needed3)7    var counted→ 0 = 0
  2. latch ← 2

    pass 1 of 2
    9for (i0 in 0 until arrivals2) {10    latch→ 2.decrementAndGet()11    counted0++12}
  3. latch ← 1

    pass 2 of 2
    9for (i1 in 0 until arrivals2) {10    latch→ 1.decrementAndGet()11    counted1++12}
  4. remaining ← 1, released ← false, status ← partial

    14    val remaining→ 1 = latch1.get()15    val released→ false = remaining1 == 01617    val status→ partial = if (counted2 == 0) {18        "waiting"19    } else if (releasedfalse) {20        "released"21    } else {22        "partial"23    }2425    println("arrivals=$arrivals2 counted=$counted2 remaining=$remaining1 $statuspartial")26}
    outputarrivals=2 counted=2 remaining=1 partial
  1. arrivals ← 0, needed ← 3, latch ← 3, counted ← 0, remaining ← 3

    3fun main() {4    val arrivals→ 0 = 05    val needed→ 3 = 36    val latch→ 3 = AtomicInteger(needed3)7    var counted→ 0 = 089    for (i in 0 until arrivals) {10        latch.decrementAndGet()11        counted++12    }1314    val remaining→ 3 = latch3.get()15    val released→ false = remaining3 == 01617    val status→ waiting = if (counted0 == 0) {18        "waiting"19    } else if (releasedfalse) {20        "released"21    } else {22        "partial"23    }2425    println("arrivals=$arrivals0 counted=$counted0 remaining=$remaining3 $statuswaiting")26}
    outputarrivals=0 counted=0 remaining=3 waiting
  1. arrivals ← 3, needed ← 3, latch ← 3, counted ← 0

    3fun main() {4    val arrivals→ 3 = 35    val needed→ 3 = 36    val latch→ 3 = AtomicInteger(needed3)7    var counted→ 0 = 0
  2. latch ← 2

    pass 1 of 3
    9for (i0 in 0 until arrivals3) {10    latch→ 2.decrementAndGet()11    counted0++12}
    All 3 passes — pass 1 is the card above
    passicountedlatch
    1003 2
    2112 1
    3221 0
  3. remaining ← 0, released ← true, status ← released

    14    val remaining→ 0 = latch0.get()15    val released→ true = remaining0 == 01617    val status→ released = if (counted3 == 0) {18        "waiting"19    } else if (releasedtrue) {20        "released"21    } else {22        "partial"23    }2425    println("arrivals=$arrivals3 counted=$counted3 remaining=$remaining0 $statusreleased")26}
    outputarrivals=3 counted=3 remaining=0 released