นากมิ้นต์สามตัวต้นฉบับยืนรอที่เส้นสตาร์ทสีอำพันบนโต๊ะมิ้นต์ จนครบจำนวนแล้วค่อยวิ่งพร้อมกัน

Java CyclicBarrier: นัดพบครบจำนวนแล้วค่อยไปต่อด้วยกัน

น้องกายEngineering

งานขนานที่ต้องรอให้ทุกคนถึงจุดเช็กพอยต์ก่อนเริ่มเฟสถัดไป ใช้ CyclicBarrier ได้ครับ ตั้งจำนวน parties แล้วให้แต่ละ thread เรียก await() เมื่อครบจะปล่อยทุกคนพร้อมกัน และ barrier รีเซ็ตใช้รอบใหม่ได้เลย

WHY: นัดพบซ้ำได้ ต่างจาก CountDownLatch ที่ใช้ครั้งเดียว

ใส่ barrierAction เป็น Runnable ที่รันโดย thread สุดท้ายที่เข้าเส้นได้ เหมาะกับสรุปรอบหรือสลับบัฟเฟอร์ก่อนเข้าเฟสถัดไป

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

public class Main {
  public static void main(String[] args) throws Exception {
    AtomicInteger rounds = new AtomicInteger();
    CyclicBarrier barrier = new CyclicBarrier(3, rounds::incrementAndGet);

    Runnable worker = () -> {
      try {
        barrier.await();
        barrier.await();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    };

    Thread[] threads = IntStream.range(0, 3)
        .mapToObj(i -> new Thread(worker))
        .toArray(Thread[]::new);
    for (Thread t : threads) t.start();
    for (Thread t : threads) t.join();

    assert rounds.get() == 2 : rounds.get();
    System.out.println("ok");
  }
}

Recap

  • ตั้ง parties ให้ตรงจำนวนผู้ร่วมงาน
  • await ครบแล้ว barrier พร้อมรอบใหม่
  • จัดการ BrokenBarrierException ถ้ามี thread พังกลางทาง