CompletableFuture 在 complete 上缓慢工作

CompletableFuture working slowly on complete

所以我已经 运行对 CompletableFuture class 进行了一些测试,并且我偶然发现了一些我无法解释的奇怪行为。

问题

我已经设法将问题减少到这个代码片段

        long nanos = System.nanoTime();
        CompletableFuture<UUID> someFuture = CompletableFuture.supplyAsync(()->{
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
            }
            return UUID.randomUUID();
        });
        someFuture.get(5, TimeUnit.SECONDS);
        System.out.println((System.nanoTime() - nanos) / 1_000_000 + "ms");

我希望这段代码在大约 10 毫秒内达到 运行。出于某种原因,运行ning 它最终花费了大约 500 毫秒!应该注意的是,这只发生在第一次执行代码时,后续执行似乎需要大约 10-15 毫秒(这是我所期望的)。

我的问题是,我可以做些什么来摆脱它,要么通过优化它,要么不使用 CompletableFuture。

我试过的

背景

我的场景(为了避免 XY 问题)是我试图通过 TCP 制作一个简单的请求-回复模型。我用 UUID 标记每个请求并将其保存在 ConcurrentHashMap<UUID, CompletableFuture<String>> 中,当数据包返回时,我从地图中获取可完成的未来并通过回复完成它。我这样做是因为预计不会按顺序回复。我遇到了 100 毫秒的延迟(虽然一直如此,不仅仅是第一次执行),即使服务器和客户端都在本地主机上 运行ning。我已经仔细检查过这个问题不是网络方面的问题,据我所知,瓶颈归结为 CompletableFuture 很慢。这样的 Map 是解决这个问题的好方法吗?如果是这样,我怎样才能消除延迟,如果不是,我将如何设计这样的东西?

来自the docs of UUID.randomUUID

Static factory to retrieve a type 4 (pseudo randomly generated) UUID. The UUID is generated using a cryptographically strong pseudo random number generator.

加密 RNG 的缺点是速度慢。因为是伪随机数生成器,生成好随机数慢的问题只有在创建随机数生成器时才存在。

如果你看一下 the OpenJDK sources of UUID.randomUUID,你会发现第一个随机数生成器是使用一个简单但有效的单例获得的,只要它被首次调用(当 class Holder 已加载):

private static class Holder {
        static final SecureRandom numberGenerator = new SecureRandom();
    } 
SecureRandom ng = Holder.numberGenerator;

作为解决方案,您可以 运行 UUID.randomUUID() 在程序启动时在后台更早地完成工作。

如果您不需要加密强度高的 UUID,您可以使用非加密强度高的 RNG 创建它们:

Random rand=new Random();//do this once

//do this whenever you need a new UUID
UUID uuid=new UUID(rand.nextLong(),rand.nextLong());