[英]How to get results from the CompletableFuture
each of "CompletableFuture.runAsync" mentioned in the code below does some calculations, an i want to get the results each time i call "CompletableFuture.runAsync". 下面的代码中提到的每个“ CompletableFuture.runAsync”都进行一些计算,每次调用“ CompletableFuture.runAsync”时,我都希望得到结果。 or in other words, i want each of "future0,future1,future2,future3" to contain the result of each call to "CompletableFuture.runAsync" respectively
或者换句话说,我希望每个“ future0,future1,future2,future3”分别包含对“ CompletableFuture.runAsync”的每次调用的结果
how can i do that. 我怎样才能做到这一点。
*Update : *更新 :
my requirements are, for each call to CompletableFuture.runAsync i do some calculations and an ArrayList of these values should be returned. 我的要求是,对于CompletableFuture.runAsync的每次调用,我都要进行一些计算,并应返回这些值的ArrayList。 and after the four calles to the CompletableFuture.runAsync , i want to some further calculations on the ArrayLists returned.
在对CompletableFuture.runAsync的四个调用之后,我想对返回的ArrayList进行一些进一步的计算。
code : 代码 :
if (this.laplaceImgList != null) {
if (!this.laplaceImgList.isEmpty()) {
if (this.laplaceImgList.size() == 3) {
//executor
ExecutorService orintMapExe;
CompletableFuture<Void> future0 = null;
CompletableFuture<Void> future1 = null;
CompletableFuture<Void> future2 = null;
CompletableFuture<Void> future3 = null;
orintMapExe = Executors.newFixedThreadPool(1);
future0 = CompletableFuture.runAsync(new orintMapRun(SysConsts.ORINT_DEG_ZERO , this.laplaceImgList), orintMapExe);
future1 = CompletableFuture.runAsync(new orintMapRun(SysConsts.ORINT_DEG_45 , this.laplaceImgList), orintMapExe);
future2 = CompletableFuture.runAsync(new orintMapRun(SysConsts.ORINT_DEG_90 , this.laplaceImgList), orintMapExe);
future2 = CompletableFuture.runAsync(new orintMapRun(SysConsts.ORINT_DEG_135 , this.laplaceImgList), orintMapExe);
CompletableFuture.allOf(future0,future1,future2,future3).join();//blocks the main thread till future0, and future1 finishes
Here I am posting an example where your job will return a Future
and you get a list of values you supply. 在这里,我发布一个示例,其中您的工作将返回“
Future
并且您会得到一个提供的值列表。 As you expect a result (List actually) it implements Callable
. 正如您期望的那样(实际上是List),它实现了
Callable
。
public class OrintMapRun implements Callable<List<Integer>> {
final int partOne, partTwo;
final List<Integer> resultList = new ArrayList<>();
public OrintMapRun(int partOne, int partTwo) {
this.partOne = partOne;
this.partTwo = partTwo;
}
@Override
public List<Integer> call() throws Exception {
resultList.add(partOne);
resultList.add(partTwo);
Thread.sleep(5000); //simulate some computation
return resultList;
}
}
Now you need to submit those Callables
to executor service as shown: 现在,您需要将这些
Callables
提交给executor服务,如下所示:
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService orintMapExe = Executors.newFixedThreadPool(4);
List<Future<List<Integer>>> futures = new ArrayList<>();
futures.add(orintMapExe.submit(new OrintMapRun(10, 10)));
futures.add(orintMapExe.submit(new OrintMapRun(20, 20)));
futures.add(orintMapExe.submit(new OrintMapRun(30, 30)));
futures.add(orintMapExe.submit(new OrintMapRun(40, 40)));
orintMapExe.shutdown();
try {
orintMapExe.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(Future<List<Integer>> future : futures) {
List<Integer> result = future.get();
System.out.println(result);
}
}
Once you get the result of all futures it will be: 一旦获得所有期货的结果,它将是:
[10, 10] [20, 20] [30, 30] [40, 40]
On a side note class name should always start with capital letter. 在旁注中,班级名称应始终以大写字母开头。
In addition to the answer from @i_am_zero, you can also use CompletionService , which is a wrapper of the simple ExecutorService. 除了@i_am_zero的答案之外,您还可以使用CompletionService ,它是简单ExecutorService的包装。 The benefit of CompletionService is that you can always get the earliest finished Future<> object and the afterward operation won't be blocked by the last finished task.
CompletionService的好处是,您始终可以获取最早完成的Future <>对象,并且后续操作不会被最后完成的任务阻止。 Based on @i_am_zero's answer, a simple improvement is like the following:
根据@i_am_zero的答案,简单的改进如下:
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService orintMapExe = Executors.newFixedThreadPool(4);
CompletionService service = new ExecutorCompletionService(orintMapExe);
List<Future<List<Integer>>> futures = new ArrayList<>();
futures.add(orintMapExe.submit(new OrintMapRun(10, 10)));
futures.add(orintMapExe.submit(new OrintMapRun(20, 20)));
futures.add(orintMapExe.submit(new OrintMapRun(30, 30)));
futures.add(orintMapExe.submit(new OrintMapRun(40, 40)));
for(int i=0; I< futures.size();i++) {
List<Integer> result = service.take().get();
System.out.println(result);
}
}
In most cases, CompletionService should be preferred than the barebone ExecutorService unless you don't care the performance. 在大多数情况下, CompletionService应该比准系统ExecutorService优先,除非您不在乎性能。 There're some good articles explaining the benefits such as https://dzone.com/articles/executorservice-vs .
有一些很好的文章解释了这些好处,例如https://dzone.com/articles/executorservice-vs 。
CompletionService is good enough for your question, but if you have interest, for CompletableFuture , I wrote up a simple blog on one scenario which is a great fit for using it: https://medium.com/@zhongzhongzhong/beauty-of-completablefuture-and-where-should-you-use-it-6ac65b7bfbe CompletionService足以解决您的问题,但是如果您有兴趣,可以针对CompletableFuture撰写一个简单的博客,其中一个场景非常适合使用它: https : //medium.com/@zhongzhongzhong/beauty-of- completablefuture-和地方,应该-您使用-IT-6ac65b7bfbe
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.