✅10个线程模拟赛马,所有马就绪后才能开跑,所有马到达终点后裁判宣布赛马成绩

这是一个比较典型的多线程之间协调的一道编程题,其实主要是考察CountDownLatch和CyclicBarrier的。

要实现这个功能,可以使用 CountDownLatch 来确保所有马都就绪后再开始比赛,并使用 CyclicBarrier 来确保所有马到达终点后裁判再宣布成绩。

/**
 * @author Hollis
 */
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class HorseRace {
    // 用于存储赛马成绩
    private static List<String> results = Collections.synchronizedList(new ArrayList<>());

    // 用于控制所有马同时开跑
    private static CountDownLatch startLatch = new CountDownLatch(1);

    // 用于确保所有马到达终点后再宣布成绩
    private static CyclicBarrier finishBarrier = new CyclicBarrier(10, new Runnable() {
        @Override
        public void run() {
            // 裁判宣布成绩
            System.out.println("Race finished! Announcing results:");
            for (String result : results) {
                System.out.println(result);
            }
        }
    });

    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            new Thread(new Horse("Horse " + i)).start();
        }

        // 所有马就绪后开跑
        try {
            System.out.println("All horses ready. Race starts now!");
            startLatch.countDown(); // 马开跑
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static class Horse implements Runnable {
        private String name;

        public Horse(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                // 马就绪,等待开跑信号
                startLatch.await();

                // 马开始跑
                long raceTime = (long) (Math.random() * 10000); // 模拟跑的时间
                Thread.sleep(raceTime);

                // 马到达终点
                results.add(name + " finished in " + raceTime + " ms");

                // 等待其他马到达终点
                finishBarrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

CountDownLatch startLatch 用于控制所有马同时开跑,初始值设为 1。使用 startLatch.await() 确保所有马就绪后再开跑。使用 startLatch.countDown() 触发所有马同时开跑。

CyclicBarrier finishBarrier 确保所有马到达终点后再执行宣布成绩的任务。使用 finishBarrier.await() 等待其他马到达终点。当所有马到达终点后,finishBarrier 的回调方法会被执行,裁判宣布赛马成绩。

原文: https://www.yuque.com/hollis666/xkm7k3/fmxgv20sy2r8hs2v