题目:百米赛跑
10个运动员进行百米赛跑,要求:
1.同时起跑
2.所有运动员都到达终点才算比赛结束
3.输出成绩排名
import java.util.ArrayList;
9/**
10 *
11 * 通过CountDownLatch和CyclicBarrier实现运动员赛跑准备->发令枪开跑->到达终点计算成绩
15 */
16public class CountDownLatchTest1 {
18 运动员数量量
19 private static int SPORTSMAN_COUNT = 10;
20
21 private static final Random random = new Random();
23 ?用于判断发令之前运动员是否已经进?入准备状态,需要等待10个运动员准备就绪,占有锁,等待10个运动员完成,释放锁。
24 private static CountDownLatch readyLatch = new CountDownLatch(SPORTSMAN_COUNT);
25 // ?用于判断裁判是否已经发令,占有锁,等待裁判发令完成,释放锁
26 private static CountDownLatch startLatch = new CountDownLatch(1);
27 // 设置终点屏障,?用于计算成绩
28 private static CyclicBarrier cb = new CyclicBarrier(SPORTSMAN_COUNT, new Runnable() { 29
30 @Override
31 public void run() {
32
33 CountDownLatchTest1.transcript
34 .sort((Sportsman p1, Sportsman p2) -> p1.getTranscript() - p2.getTranscript());
35
36 System.out.println("排名成绩单:" + CountDownLatchTest1.transcript);
37
38 CountDownLatchTest1.transcript.clear();
39 }
40 });
41
42 // 成绩单
43 private static List transcript = new ArrayList(SPORTSMAN_COUNT);
44
45 public static void main(String[] args) {
47 ?用于判断发令之前运动员是否已经进?入准备状态,需要等待10个运动员准备就绪,占有锁,等待10 个运动员完成,释放锁。
48 // CountDownLatch readyLatch = new CountDownLatch(SPORTSMAN_COUNT);
49 // ?用于判断裁判是否已经发令,占有锁,等待裁判发令完成,释放锁
50 // CountDownLatch startLatch = new CountDownLatch(1);
52 启动10个线程,也就是10个运动员,做准备?工作
53 for (int i = 0; i < SPORTSMAN_COUNT; i++) {
54 Thread t = new Thread(new RunTask((i + 1) + "号运动员", readyLatch, startLatch));
55 t.start();
57 //当前运动员在其他运动员准备就绪前?一直等待,也就是说等readyLatch倒数计数器?为0之前?一直等待
58 try {
59 readyLatch.await();
60 } catch (InterruptedException e) {
61 e.printStackTrace();
63 // 裁判发令,释放锁
64 startLatch.countDown();
65 System.out.println("裁判:所有运动员准备完毕,开始跑...");
66
67 }
68
69 // 运动员
70 static class Sportsman { 71 private String name;
72 private int transcript;
73
74 public Sportsman(String name, int transcript) {
75 this.name = name;
76 this.transcript = transcript;
77 }
78
79 @Override
80 public boolean equals(Object obj) { 81 boolean result = false;
82 if (obj instanceof Sportsman) {
83 result = ((Sportsman) obj).getTranscript() == this.transcript;
84 }
85 return result;
86 }
87
88 @Override
89 public String toString() {
90 return this.name + ":" + this.transcript + " ms";
91 }
92
93 public String getName() {
94 return name;
95 }
96
97 public int getTranscript() {
98 return transcript;
99 }
100
101 }
102
103 // 跑任务
104 static class RunTask implements Runnable { 105
106 private Lock lock = new ReentrantLock();
107
108 private CountDownLatch ready;
109 private CountDownLatch start;
110 private String name;
111
112 /**
113 *
114 * (构造?方法)
115 *
116 * @param ready
117 * @param start
118 * @param name 运动员名称
119 */
120 public RunTask(String name, CountDownLatch ready, CountDownLatch start) {
121 this.ready = ready;
122 this.start = start;
123 this.name = name;
124 }
125
126 @Override
127 public void run() {
128 lock.lock();
129 try {
130
131 // 1. 写运动员准备就绪的逻辑,准备readyTime秒
132 int readyTime = random.nextInt(1000);
133 System.out.println(name + ":我需要" + readyTime + "秒的时间准备。");
134 try {
135 Thread.sleep(readyTime);
136 } catch (InterruptedException e) {
137 e.printStackTrace();
138 }
139 System.out.println(name + "我已经准备完毕!"); 140 // 释放锁readyLatch-1,表示?一个运动员已经就绪
141 ready.countDown();
143 待裁判发开始命令
144 start.await();
145 } catch (InterruptedException e) {
146
147 }
148 System.out.println(name + ":开跑...");
149 int costTime = random.nextInt(500);
150 try {
151 Thread.sleep(costTime);
152 } catch (InterruptedException e) {
153 e.printStackTrace();
154 }
155 System.out.println(name + ":开跑到达终点。成绩:" + costTime + "ms");
156 transcript.add(new Sportsman(name, costTime));
157 // 等待成绩
158 cb.await();
159 } catch (Exception e) {
160
161 } finally {
162 lock.unlock();
163 }
164
165 }
166
167 }
168
169}
原文:https://www.cnblogs.com/cdlyy/p/12061146.html