这是一个比较典型的多线程之间协调的一道编程题,其实主要是考察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 的回调方法会被执行,裁判宣布赛马成绩。