zoukankan      html  css  js  c++  java
  • 多线程-百米赛跑

    题目:百米赛跑
    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();
                    }
            }
        }
    }



  • 相关阅读:
    Magento 安装时文件权限 设置
    进度十(10.28)
    进度九(10.27)
    进度八(10.26)
    进度六(10.24)
    进度五(10.23)
    进度四(10.22)
    进度三(10.21)
    进度二(10.20)
    进度一(10.19)
  • 原文地址:https://www.cnblogs.com/cdlyy/p/12061146.html
Copyright © 2011-2022 走看看