具有可完成未来的Java 8并行处理


每天我们都会看到编程用例,这些用例应并行处理数据以提高性能。在Java 8中,CompletableFuture我们可以实现并行编程更简单,可读的方式用类似的方法allOf,join等等。

每当我们调用任何方法时,都必须决定是否需要该方法的任何返回值。如果我们不想要任何返回值,我们可以调用该方法并将控件留给它。CompletableFuture我们有2种方法可以解决上述情况:

CompletableFuture.supplyAsync —如果需要返回值。 CompletableFuture.runAsync —如果您不希望返回值。 因此,让我们举个例子,我们正在执行3个必须并行执行的任务。

方法1:添加->接受2变量的参数并返回总和

public static  Integer  addFun1(int a, int b) {
        System.out.println(Thread.currentThread().getName());
        for (int i=0;i<10;i++){
            System.out.print(Thread.currentThread().getName()+i);
        }
        return  a+b ;
    }

方法2:sub->接受2变量的参数并返回减法

public static  Integer  subFun1(int a, int b) {
        System.out.println(Thread.currentThread().getName());
        for (int i=0;i<10;i++){
            System.out.print(Thread.currentThread().getName()+i);
        }
        return  a-b ;
    }

方法3:mul->接受2变量的参数并返回乘法

public static  Integer  mulFun1(int a, int b) {
        System.out.println(Thread.currentThread().getName());
        for (int i=0;i<10;i++){
            System.out.print(Thread.currentThread().getName()+i);
        }
        return  a*b ;
    }

实际的CompletableFuture工作从这里开始。在添加期货之前,我们必须维护一个将所有未来列表捆绑在一起的全局列表:

List<CompletableFuture<Integer>> futuresList = new ArrayList<CompletableFuture<Integer>>();

然后,必须将我们创建的必须并行运行的CompletableFuture方法声明为方法。

CompletableFuture<Integer> addAsy = CompletableFuture.supplyAsync(()->(addFun1(10,5)));
CompletableFuture<Integer> subAsy = CompletableFuture.supplyAsync(()->(subFun1(10,5)));
CompletableFuture<Integer> mulAsy = CompletableFuture.supplyAsync(()->(mulFun1(10,5)));

因此,上述方法被转换为可以并行处理的可完成期货。正如我们在上一行中所述,所有期货都添加到了全球期货列表中。

futuresList.add(addAsy);
futuresList.add(subAsy);
futuresList.add(mulAsy);

然后,我们必须写一行,使所有线程之间保持一致,说:“等到参数中的所有线程完成为止”。为此,我们必须使用该allOf方法。

CompletableFuture<Void> allFutures = CompletableFuture
                .allOf(futuresList.toArray(new CompletableFuture[futuresList.size()]));

然后,我们必须写一行,“在完成所有线程的执行后,收集所有线程的所有返回值”。

CompletableFuture<List<Integer>> allCompletableFuture = allFutures.thenApply(future -> {
            return futuresList.stream().map(completableFuture -> completableFuture.join())
                    .collect(Collectors.toList());
        });

最后,将将来清单定义为可完成的将来。

CompletableFuture<List<Integer>> completableFuture = allCompletableFuture.toCompletableFuture();

所有设置均已完成,以便使用可完成的将来进行并行处理。要调用整个并行方法,下面是使用get()的代码行

try {
            List<Integer> finalList = (List<Integer>) completableFuture.get();
            System.out.print(finalList);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

您将在finalList变量中获得所有结果。

为了使事情更清楚,我在每个方法内编写了一个for循环,以多次处理sysout,从而使该方法中的每个线程都有更多时间。

执行完程序后,只需分析sysout注释并跟踪控件以更好地理解。


原文链接:https://codingdict.com/