群里得一面试题,正好用来练手

现有一场田径比赛,共有8个选手参赛。他们编号分别为: A,B,C,D,E,F,G,H; 赛事观察员分别在开始后 20s和30s拍下两张照片,各个选手的排名情况如下, 20s:F,A,H,G,C,B,E,D;30s:G,H,A,C,F,D,B,E;请你写出一个程序, 模拟出这些参赛选手在20-30s这10s的内排名变化,每1s显示一次排名。

主要是考察countDownLatch。
计算的时候clone出快照。避免计算的过程中瞬间值又有变化,导致算出的值不准确。

拍照也就是存一下快照而已。
ps:可能是对题理解有误,下面的效果不追求固定名次。
固定名次的写法思路是:写死 各个选手在20s的时候的距离(a),根据a减去各个选手当前的距离(0),然后再 随机到每一秒,就是选手每秒的跑的距离。 30s 的时候重新定义一下目标距离(b),b减去选手的20s时候的距离a,随机到每一秒。

效果

代码

package com.gkwind.concurrent;import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;/*** 现有一场田径比赛,共有8个选手参赛。他们编号分别为: A,B,C,D,E,F,G,H;* 赛事观察员分别在开始后   20s和30s拍下两张照片,各个选手的排名情况如下,* 20s:F,A,H,G,C,B,E,D;30s:G,H,A,C,F,D,B,E;请你写出一个程序,* 模拟出这些参赛选手在20-30s这10s的内排名变化,每1s显示一次排名。** @Author thewindkee* @Date 2019/7/18 0018  22:36*/
public class Athletics {static final CountDownLatch START_GUN = new CountDownLatch(1);static final LocalDateTime DATE_TIME = LocalDateTime.now();static volatile boolean over = false;static long startTime;static final int PICTURE_TIME = 20;static final int PICTURE_TIME2 = 30;public static void main(String[] args) throws InterruptedException {int num = 8;CountDownLatch latch = new CountDownLatch(num);List<Athlete> athletes = initAthletes(num, latch);athletes.stream().forEach(athlete -> athlete.start());System.out.println("裁判等待选手就位");Computer computer = new Computer(athletes);computer.start();latch.await();System.out.println(DATE_TIME + "时裁判开枪");startTime = Instant.now().toEpochMilli();START_GUN.countDown();computer.join();computer.showPhotos();}private static List<Athlete> initAthletes(int num, CountDownLatch latch) {return IntStream.range(0, num).mapToObj(i -> new Athlete(String.valueOf((char) ('A' + i)), latch)).collect(Collectors.toList());}static class Computer extends Thread {List<Picture<Athlete>> pictures = new ArrayList<>();static class Picture<E> {final List<E> pictureItems;final long timestamp;public Picture(List<E> items) {this.pictureItems = Collections.unmodifiableList(items);;this.timestamp = Instant.now().toEpochMilli();}public void show() {pictureItems.stream().forEach(item -> System.out.println(item));}@Overridepublic String toString() {return "照片拍摄于" + LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()) +":" + pictureItems +'}';}}final List<Athlete> athletes;public Computer(List<Athlete> athletes) {this.athletes = Collections.unmodifiableList(athletes);}public List<Athlete> compute() {return athletes.stream().map(new Function<Athlete, Athlete>() {@Overridepublic Athlete apply(Athlete athlete) {try {//拍照,返回运动员的成绩快照return (Athlete) athlete.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}throw new RuntimeException("计算机故障");}}).sorted(Comparator.reverseOrder()).collect(Collectors.toList());}@Overridepublic void run() {try {System.out.println("电脑已启动");START_GUN.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("\n电脑开始工作");sleepThenTakeFirstPhoto();while (!over && !isInterrupted()) {System.out.println();long currentSecond = (Instant.now().toEpochMilli() - startTime) / 1000 + 1;try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}List<Athlete> sortedAthletes = compute();System.out.print(currentSecond + "秒: ");sortedAthletes.stream().forEach(athlete -> System.out.print(athlete.getName() + " " + athlete.curLength + " "));if (currentSecond >= PICTURE_TIME2) {//第二次拍照takePhoto(sortedAthletes);over = true;break;}}}private void sleepThenTakeFirstPhoto() {while (true) {long currentSecond = (Instant.now().toEpochMilli() - startTime) / 1000 + 1;try {TimeUnit.SECONDS.sleep(1);System.out.print(currentSecond + "秒  ");} catch (InterruptedException e) {e.printStackTrace();}if (PICTURE_TIME <= currentSecond) {System.out.println(currentSecond + "秒");//第一次拍照List<Athlete> sortedAthletes = compute();System.out.print(currentSecond + "秒: ");sortedAthletes.stream().forEach(athlete -> System.out.print(athlete.getName() + " " + athlete.curLength + " "));takePhoto(sortedAthletes);break;}}}private <E> void takePhoto(List<E> datas) {System.out.print("\ttakePhoto");pictures.add(new Picture(datas));}public void showPhotos() {System.out.println("\n打印照片");pictures.stream().forEach(e -> System.out.println(e));}}static class Athlete extends Thread implements Comparable<Athlete>, Cloneable {final CountDownLatch latch;final String name;private volatile int curLength = 0;public Athlete(String name, CountDownLatch latch) {super(name);this.name = name;this.latch = latch;}public void ready() {System.out.println(this.name + " 进场");try {TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(100));} catch (InterruptedException e) {e.printStackTrace();}System.out.println("选手" + this.name + " 准备好了,等待发令枪");latch.countDown();}@Overridepublic void run() {ready();try {START_GUN.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.print("选手" + this.name + " 起跑\t");doRun();}private void doRun() {while (!over && !isInterrupted()) {curLength += ThreadLocalRandom.current().nextInt(8)+1;//模拟秒速try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}@Overridepublic int compareTo(Athlete o) {return Integer.compare(this.curLength, o.curLength);}@Overrideprotected Object clone() throws CloneNotSupportedException {Athlete athlete = new Athlete(this.name, null);athlete.curLength = this.curLength;return athlete;}@Overridepublic String toString() {return "Athlete{" +"name='" + name + '\'' +", curLength=" + curLength +'}';}}
}

CountDownLatch模拟田径赛跑相关推荐

  1. 用CountDownLatch模拟跑步比赛

    示例代码 public class Test {//比赛开始的倒计时private static CountDownLatch countDownLatchStart = new CountDownL ...

  2. 使用CyclicBarrier模拟百米赛跑

    使用CyclicBarrier模拟百米赛跑 什么是CyclicBarrier 怎么使用CyclicBarrier 使用CyclicBarrier模拟百米赛跑 大概流程: 原代码 输出结果 什么是Cyc ...

  3. 使用CountDownLatch模拟高并发场景

    import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java ...

  4. phaser模拟百米赛跑

    package com.brendan.cn.concurrent.match;import java.util.concurrent.Phaser;public class Match {// 模拟 ...

  5. java count 在哪一类里_java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用...

    先来讲解一下Semaphore信号灯的作用: 可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面的 ...

  6. java不完全教程附编码示例

    Java不完全教程第一章Java预备知识常用DOS命令help,dir,md,cd,rd,del,copy,move,start,type,cls,attrib配置环境变量JAVA_HOME C:\s ...

  7. java小车赛跑_Java模拟赛跑过程

    Java并发面试中的一个经典问题--手写代码模拟赛跑过程.该问题考查CountDownLatch的用法,比Java实现生产者-消费者模型的考查更直接: 对Java并发模型的理解 对Java并发编程接口 ...

  8. Java CountDownLatch的两种常用场景

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120506758 本文出自[赵彦军的博客] 文章目录 简介 场景1 让多个线程等待: ...

  9. Java 模拟多线程并发案例

    一.使用 CountDownLatch 模拟多线程并发(并行) CountDownLatch 介绍: countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBar ...

最新文章

  1. java list《》_Java中List集合的遍历
  2. 鸿蒙兼容安卓app 为什么还要生态,就因为鸿蒙兼容安卓APP,中兴就宣布弃用?...
  3. 今日arXiv精选 | 9篇ICCV 2021最新论文
  4. 用shell批量转储表
  5. eclipse代码编辑区字符串自动转义设置
  6. (七)、Java异常类型及处理
  7. 关于字体的一些知识,以及分享一些免费可商用字体
  8. 云服务器Tomcat版本升级(Tomcat6升级至Tomcat7和Tomcat8)问题总结
  9. 国际贸易基础(三)商检
  10. 代码粘贴至word后,黑色背景处理
  11. 翼灵物联工作室第一次考试总结
  12. 学习CSS的background属性及其取值(实践)
  13. 如何用几何绘图软件给半圆填色?
  14. linux gzip 4G,Linux gzip命令
  15. 关于C++中Eigen库效率提升的思考
  16. eclipse开发android入门学习
  17. php如何继续提升技术?一个php技术栈后端猿的知识储备仓库
  18. DELPHI HOOK随手笔记
  19. 无领导小组讨论面试真题解析(三)
  20. Jenkins 流水线说明

热门文章

  1. windows系统 桌面时钟控件
  2. me shy是什么歌 抖音make_抖音歌词make me shy –抖音shy是什么歌 抖音shy歌曲分享
  3. qt 实现的 lua 编辑器
  4. 开机grub命令修复方法linux,开机grub命令修复方法
  5. 补码的加减运算和溢出判断
  6. 电脑上的以太网连接,本地连接,宽带连接,无线WLAN连接的区别(超详细)
  7. React源码解读之React Fiber
  8. React Fiber 机制
  9. “人为什么要工作” 劳动究竟为了什么?
  10. IT运维的365天--006Win7设置防火墙允许他人ping测试