CountDownLatch模擬陸上競技
8815 ワード
グループの中で面接の問題があって,ちょうど手を練習するのに使われている.
現在陸上競技が1試合あり、8選手が出場している.彼らの番号はそれぞれ:A,B,C,D,E,F,G,H;試合オブザーバーはそれぞれ開始後20 sと30 sに2枚の写真を撮り、各選手の順位は以下の通り、20 s:F、A、H、G、C、B、E、D;30s:G,H,A,C,F,D,B,E;これらの参加選手が20-30 sの10 s以内の順位の変化をシミュレートし、1 sごとに順位を表示するプログラムを書いてください.
主にcountDownLatchを考察する.計算時にcloneがスナップショットを出します.計算中に瞬間値が変化することを避け、算出された値が不正確になる.
写真を撮るのはスナップショットを保存するだけです.ps:問題の理解が間違っているかもしれませんが、次の効果は固定順位を追求しません.固定順位の書き方は、各選手が20 sのときの距離(a)を書き殺し、aから各選手の現在の距離(0)を減算し、ランダムに毎秒、つまり選手が毎秒走る距離とする.30 sのときに目標距離(b)を再定義し、bから選手の20 sを引いたときの距離aをランダムに毎秒にする.
効果
コード#コード#
現在陸上競技が1試合あり、8選手が出場している.彼らの番号はそれぞれ:A,B,C,D,E,F,G,H;試合オブザーバーはそれぞれ開始後20 sと30 sに2枚の写真を撮り、各選手の順位は以下の通り、20 s:F、A、H、G、C、B、E、D;30s:G,H,A,C,F,D,B,E;これらの参加選手が20-30 sの10 s以内の順位の変化をシミュレートし、1 sごとに順位を表示するプログラムを書いてください.
主にcountDownLatchを考察する.計算時にcloneがスナップショットを出します.計算中に瞬間値が変化することを避け、算出された値が不正確になる.
写真を撮るのはスナップショットを保存するだけです.ps:問題の理解が間違っているかもしれませんが、次の効果は固定順位を追求しません.固定順位の書き方は、各選手が20 sのときの距離(a)を書き殺し、aから各選手の現在の距離(0)を減算し、ランダムに毎秒、つまり選手が毎秒走る距離とする.30 sのときに目標距離(b)を再定義し、bから選手の20 sを引いたときの距離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 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 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> pictures = new ArrayList<>();
static class Picture {
final List pictureItems;
final long timestamp;
public Picture(List items) {
this.pictureItems = Collections.unmodifiableList(items);
;
this.timestamp = Instant.now().toEpochMilli();
}
public void show() {
pictureItems.stream().forEach(item -> System.out.println(item));
}
@Override
public String toString() {
return " " + LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()) +
":" + pictureItems +
'}';
}
}
final List athletes;
public Computer(List athletes) {
this.athletes = Collections.unmodifiableList(athletes);
}
public List compute() {
return athletes.stream().map(new Function() {
@Override
public Athlete apply(Athlete athlete) {
try {
// ,
return (Athlete) athlete.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
throw new RuntimeException(" ");
}
}).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
}
@Override
public void run() {
try {
System.out.println(" ");
START_GUN.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("
");
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 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 sortedAthletes = compute();
System.out.print(currentSecond + " : ");
sortedAthletes.stream().forEach(athlete -> System.out.print(athlete.getName() + " " + athlete.curLength + " "));
takePhoto(sortedAthletes);
break;
}
}
}
private void takePhoto(List datas) {
System.out.print("\ttakePhoto");
pictures.add(new Picture(datas));
}
public void showPhotos() {
System.out.println("
");
pictures.stream().forEach(e -> System.out.println(e));
}
}
static class Athlete extends Thread implements Comparable, 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();
}
@Override
public 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();
}
}
}
@Override
public int compareTo(Athlete o) {
return Integer.compare(this.curLength, o.curLength);
}
@Override
protected Object clone() throws CloneNotSupportedException {
Athlete athlete = new Athlete(this.name, null);
athlete.curLength = this.curLength;
return athlete;
}
@Override
public String toString() {
return "Athlete{" +
"name='" + name + '\'' +
", curLength=" + curLength +
'}';
}
}
}