日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

有一個賽跑比賽,4個人參賽,給前三名頒發得金銀銅牌,用代碼怎么寫呢

 

//運動員
@Data
@RequiredArgsConstructor
public static class Runner {
    private final String name;
    private Integer score;
}
// 頒獎類
public static class AwardUtils {
    private static BlockingQueue<String> awardQueue = new LinkedBlockingQueue<>(3);
    static {
        awardQueue.offer("金牌");
        awardQueue.offer("銀牌");
        awardQueue.offer("銅牌");
    }
    public static void winAward(String name) {
        String award = awardQueue.poll();
        if (award != null) {
            log.info("{} 獲得了 {}", name,  award);
        } else {
            log.info("{} 沒有獲得獎牌", name);
        }
    }
}

普通做法:我們可以等運動員跑玩,看誰用時少來頒獎

CountDownLatch countDownLatch = new CountDownLatch(1);
// 賽跑任務
Function<Runner, Callable<Runner>> runTask = (runner) -> () -> {
    countDownLatch.await();
    int time = ThreadLocalRandom.current().nextInt(10, 20);
    runner.setScore(time);
    TimeUnit.SECONDS.sleep(time);
    log.info("{} 跑了 {} 秒", runner.getName(), time);
    return runner;
};
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<Runner>> results = Arrays.asList(
        executor.submit(runTask.Apply(new Runner("小明"))),
        executor.submit(runTask.apply(new Runner("小鵬"))),
        executor.submit(runTask.apply(new Runner("小張"))),
        executor.submit(runTask.apply(new Runner("小李")))
);
countDownLatch.countDown();
results.stream().map(future -> {
    try {
        return future.get(20, TimeUnit.SECONDS);
    } catch (TimeoutException | InterruptedException | ExecutionException e) {
        throw new RuntimeException(e);
    }
}).sorted((runner1, runner2) -> {
    int score1 = runner1.getScore();
    int score2 = runner2.getScore();
    return Integer.compare(score1, score2);
}).forEach(runner -> {
    AwardUtils.winAward(runner.getName());
});
11:21:38,915 [pool-1-thread-2] INFO - 小鵬 跑了 11 秒
11:21:42,908 [pool-1-thread-4] INFO - 小李 跑了 15 秒
11:21:43,901 [pool-1-thread-3] INFO - 小張 跑了 16 秒
11:21:43,901 [pool-1-thread-1] INFO - 小明 跑了 16 秒
11:21:43,902 [main] INFO - 小鵬 獲得了 金牌
11:21:43,902 [main] INFO - 小李 獲得了 銀牌
11:21:43,902 [main] INFO - 小明 獲得了 銅牌
11:21:43,902 [main] INFO - 小張 沒有獲得獎牌

CompletionService:有人跑完了就把獎牌給他,不用等其他人是否跑完
主要功能就是一邊執行任務,一邊獲取任務的返回值。讓兩件事分開執行,任務之間不會互相阻塞,可以實現先執行完的先取結果,不依賴任務順序

CountDownLatch countDownLatch = new CountDownLatch(1);
Function<Runner, Callable<Runner>> runTask = (runner) -> () -> {
    countDownLatch.await();
    int time = ThreadLocalRandom.current().nextInt(10, 20);
    runner.setScore(time);
    TimeUnit.SECONDS.sleep(time);
    log.info("{} 跑了 {} 秒", runner.getName(), time);
    return runner;
};
ExecutorService executor = Executors.newFixedThreadPool(4);
CompletionService<Runner> completionService = new ExecutorCompletionService<>(executor);
completionService.submit(runTask.apply(new Runner("小明")));
completionService.submit(runTask.apply(new Runner("小鵬")));
completionService.submit(runTask.apply(new Runner("小張")));
completionService.submit(runTask.apply(new Runner("小李")));
countDownLatch.countDown();
for (int i = 0; i < 4; i++) {
    AwardUtils.winAward(completionService.take().get().getName());
}
11:11:15,125 [pool-1-thread-3] INFO  - 小張 跑了 10 秒
11:11:15,130 [main] INFO  - 小張 獲得了 金牌
11:11:19,122 [pool-1-thread-1] INFO   - 小明 跑了 14 秒
11:11:19,122 [main] INFO   - 小明 獲得了 銀牌
11:11:20,125 [pool-1-thread-4] INFO   - 小李 跑了 15 秒
11:11:20,125 [main] INFO   - 小李 獲得了 銅牌
11:11:22,132 [pool-1-thread-2]  - 小鵬 跑了 17 秒
11:11:22,132 [main] INFO  - 小鵬 沒有獲得獎牌

ExecutorCompletionService 類中維護一個了 BlockingQueue;

public class ExecutorCompletionService<V> implements CompletionService<V> {
    private final BlockingQueue<Future<V>> completionQueue;
    public Future<V> submit(Callable<V> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<V> f = newTaskFor(task);
        executor.execute(new QueueingFuture(f));
        return f;
    }
}

QueueingFuture 重寫了done 方法 ,done 方法會在完成或取消任務時執行,將其加入隊列

private class QueueingFuture extends FutureTask<Void> {
    QueueingFuture(RunnableFuture<V> task) {
        super(task, null);
        this.task = task;
    }
    protected void done() { completionQueue.add(task); }
    private final Future<V> task;
}

分享到:
標簽:JDK
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定