针对Reactor(或Akka)解决方案的CompletableFuture解决方案

时间:2018-04-30 02:36:11

标签: java java-8 akka project-reactor reactive-streams

我使用CompletableFuture这样的方法如下:

public AClass aMethod() {

    CompletableFuture<SomeClassA> someClassAFuture =
        CompletableFuture.supplyAsync(() -> someMethodThatReturnsA());
    CompletableFuture<SomeClassB> someClassBFuture =
        CompletableFuture.supplyAsync(() -> someMethodThatReturnsB());
    CompletableFuture<SomeClassC> someClassCFuture =
        CompletableFuture.supplyAsync(() -> someMethodThatReturnsC());

    CompletableFuture.allOf(someClassAFuture, someClassBFuture, someClassCFuture).join();

    return new AClass(someClassAFuture.join(), someClassBFuture.join(), someClassCFuture.join());
}

如果fork join pool中的线程数少于T,则T * 3个线程同时进入该方法时,此代码会出现死锁问题(因为allOf调用都不能完成,并且它们不会返回当前采用的线程池。

我找到解决此问题的唯一方法是限制方法内的同步线程(使用Spring {#1}}注释与线程执行程序)或增加fork连接池中的线程。 / p>

我想要一些更好的解决方案,我可以完全忘记线程池的大小。如何使用Reactor或Akka重写此内容?

1 个答案:

答案 0 :(得分:0)

Akka期货的实施将是(完全未经测试的):

Future< SomeClassA > f1 = future(() -> someMethodThatReturnsA(), system.dispatcher());
Future< SomeClassB > f2 = future(() -> someMethodThatReturnsB(), system.dispatcher());
Future< SomeClassC > f3 = future(() -> someMethodThatReturnsC(), system.dispatcher());

List<Future<Object>> futures = Arrays.asList(f1, f2, f3);

return sequence(futures).map((results) ->  new AClass(results.get(0),results.get(1),results.get(2)));

在创建AClass之前,可能需要一些额外的工作来解析期货结果。请注意,您现在正在Future< AClass >

中返回aMethod

但是,代码的问题在于它是阻塞的。您是否尝试使用thenApplythenCompose加入所有CompletableFutures以返回CompletableFuture<AClass>