最近,我正在做一个项目,在这个项目中,我可以同时进行2个异步调用。由于我正在使用Quarkus,所以我最终试图使用Mutiny和vert.x库。但是,我无法让我的代码与Unis一起工作。在下面的代码中,我可以想象会调用Unis,返回返回最快的Uni。然而,在合并Unis时,它似乎只是返回列表中的第一个,尽管第一个uni需要更长的时间。
下面的代码打印出one one时应该打印出two two,因为uniFast应该先完成。如何将Unis合并,先返回速度更快的Unis?
@Test
public void testUniJion(){
var uniSLow = Uni.createFrom().item(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "one";
});
var uniFast = Uni.createFrom().item(() -> {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "two";
});
var resp = Uni.join().first(uniSLow,uniFast).withItem().await().indefinitely();
System.out.println(resp);
var resp2 = Uni.combine().any().of(uniSLow,uniFast).await().indefinitely();
System.out.println(resp2);
}注意:这不是我要实现的实际代码。在我的代码中,我试图从两个不同的数据库中获取。但是,一个数据库的延迟往往比另一个数据库大得多。然而,Uni似乎总是等待较慢的数据库。我只是想更好地理解Mutiny和Uni,所以我做了这个代码示例。
发布于 2022-06-16 18:22:55
问题是,您没有告诉Mutiny应该在哪个线程上运行每个uni。如果我在您的示例中添加一个System.out:
// Slow and Fast for the different Uni
System.out.println( "Slow - " + Thread.currentThread().getId() + ":" + Thread.currentThread().getName() );我得到以下输出:
Slow - 1:Test worker
one
Slow - 1:Test worker
Fast - 1:Test worker
one输出显示,所有的东西都运行在同一个线程上,因此当我们阻塞第一个线程时,第二个线程也会被阻塞。这就是输出为one one的原因。
并行运行uni的一种方法是在订阅时使用不同的执行程序:
ExecutorService executorService = Executors.newFixedThreadPool( 5 );
uniSlow = uniSlow.runSubscriptionOn( executorService );
uniFast = uniFast.runSubscriptionOn( executorService );现在,当我运行测试时,我有了预期的输出:
Slow - 16:pool-3-thread-1
Fast - 17:pool-3-thread-2
two
Slow - 18:pool-3-thread-3
Fast - 19:pool-3-thread-4
two请注意,这次慢速和快速运行在不同的线程上。
变形指南中有一个关于emitOn对runSubscriptionOn和关于如何更改排放线程的一些示例之间的区别的章节。
https://stackoverflow.com/questions/72647827
复制相似问题