多线程-百米赛跑

题目:百米赛跑
10个运动员进行百米赛跑,要求:
1.同时起跑
2.所有运动员都到达终点才算比赛结束
3.输出成绩排名

java代码实现如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CountDownLatchTest {
    //运动员数量量
    private static int SPORTSMAN_COUNT = 10;
    private static final Random random = new Random();
    //用于判断发令之前运动员是否已经进⼊入准备状态,需要等待10个运动员准备就绪,占有锁,等待10个运动员完成,释放锁。
    private static CountDownLatch readyLatch = new CountDownLatch(SPORTSMAN_COUNT);
    // ⽤用于判断裁判是否已经发令,占有锁,等待裁判发令完成,释放锁
    private static CountDownLatch startLatch = new CountDownLatch(1);
    // 设置终点屏障,⽤用于计算成绩
    private static CyclicBarrier cb = new CyclicBarrier(SPORTSMAN_COUNT, new Runnable() {

        @Override
        public void run() {
            CountDownLatchTest.transcript.sort((Sportsman p1, Sportsman p2) -> p1.getTranscript() - p2.getTranscript());
            System.out.println("排名成绩单:" + CountDownLatchTest.transcript);
            CountDownLatchTest.transcript.clear();
        }
    });
    // 成绩单
    private static List<Sportsman> transcript = new ArrayList<Sportsman>(SPORTSMAN_COUNT);

    public static void main(String[] args) {
        //用于判断发令之前运动员是否已经进⼊准备状态,需要等待10个运动员准备就绪,占有锁,等待10 个运动员完成,释放锁。
        // CountDownLatch readyLatch = new CountDownLatch(SPORTSMAN_COUNT);
        // ⽤用于判断裁判是否已经发令,占有锁,等待裁判发令完成,释放锁
        // CountDownLatch startLatch = new CountDownLatch(1);
        // 启动10个线程,也就是10个运动员,做准备⼯工作
        for (int i = 0; i < SPORTSMAN_COUNT; i++) {
            Thread t = new Thread(new RunTask((i + 1) + "号运动员", readyLatch, startLatch));
            t.start();
            }
            //当前运动员在其他运动员准备就绪前⼀一直等待,也就是说等readyLatch倒数计数器器为0之前⼀一直等待
            try {
                readyLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
                //裁判发令,释放锁
                startLatch.countDown();
                System.out.println("裁判:所有运动员准备完毕,开始跑...");
        }

        /**运动员类*/
        static class Sportsman {
            private String name;
            private int transcript;
            public Sportsman(String name, int transcript) {
                this.name = name;
                this.transcript = transcript;
            }

            @Override
            public boolean equals(Object obj) {
                 boolean result = false;
                if (obj instanceof Sportsman) {
                    result = ((Sportsman) obj).getTranscript() == this.transcript;
                }
                return result;
            }

            @Override
            public String toString() {
                return this.name + ":" + this.transcript + " ms";
            }
            public String getName() {
                return name;
            }
            public int getTranscript() {
                return transcript;
            }
        }
        /** 跑任务类*/
        static class RunTask implements Runnable {
            private Lock lock = new ReentrantLock();
            private CountDownLatch ready;
            private CountDownLatch start;
            private String name;
            /**
             * (构造⽅方法)
             * @param ready
             * @param start
             * @param name  运动员名称
             */
            public RunTask(String name, CountDownLatch ready, CountDownLatch start) {
                this.ready = ready;
                this.start = start;
                this.name = name;
            }

            @Override
            public void run() {
                lock.lock();
                try {
                    // 运动员准备就绪的逻辑,准备readyTime秒
                    int readyTime = random.nextInt(1000);
                    System.out.println(name + ":我需要" + readyTime + "秒的时间准备。");
                    try {
                        Thread.sleep(readyTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + "我已经准备完毕!");
                    // 释放锁readyLatch-1,表示⼀一个运动员已经就绪
                    ready.countDown();
                    //待裁判发开始命令
                    try{
                        start.await();
                    } catch (InterruptedException e) {
                    }
                    System.out.println(name + ":开跑...");
                    int costTime = random.nextInt(500);
                    try {
                        Thread.sleep(costTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + ":开跑到达终点。成绩:" + costTime + "ms");
                    transcript.add(new Sportsman(name, costTime));
                    // 等待成绩
                    cb.await();
                } catch(Exception e) {
                } finally {
                    lock.unlock();
                }
        }
    }
}

 




posted @ 2019-12-18 17:43  初仰  阅读(848)  评论(0)    收藏  举报