如何在Java中并行运行多个方法并获取每个方法的输出。

huangapple go评论122阅读模式
英文:

How to run multiple methods parallely and get outputs from each of them in java

问题

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class test {

    public static void main(String[] args) {
        String total = "";

        Callable<String> callable1 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                String t1 = "";
                t1 = method1();
                return t1;
            }
        };

        Callable<String> callable2 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                String t2 = method2();
                return t2;
            }
        };

        Callable<String> callable3 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                String t3 = method3();
                return t3;
            }
        };

        List<Callable<String>> taskList = new ArrayList<Callable<String>>();
        taskList.add(callable1);
        taskList.add(callable2);
        taskList.add(callable3);

        ExecutorService executor = Executors.newFixedThreadPool(3);

        try {
            List<java.util.concurrent.Future<String>> futures = executor.invokeAll(taskList);
            for (java.util.concurrent.Future<String> future : futures) {
                total += future.get();
            }

            System.out.println(total);
        } catch (InterruptedException ie) {
            // do something if you care about interruption;
        } catch (java.util.concurrent.ExecutionException ee) {
            // handle exception if one of the tasks threw an exception
        }

        executor.shutdown();
    }

    public static String method1() {
        System.out.println("method1");
        return "1";
    }

    private static String method2() {
        System.out.println("method2");
        return "2";
    }

    private static String method3() {
        System.out.println("method3");
        return "3";
    }
}
英文:

I want to run three different methods in parallel to improve the performance in Java. Also I need to get the outputs from all the three of them. Below is the sample which I have tried. here, I'm not sure how to retrieve the returned string values. Please help me to add(concatenate all the three strings to total).

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class test {
public static void main(String[] args) {
String total = &quot;&quot;;
Callable&lt;String&gt; callable1 = new Callable&lt;String&gt;()
{
@Override
public String call() throws Exception
{
String t1 = &quot;&quot;;
t1 = method1();
return t1;
}
};
Callable&lt;String&gt; callable2 = new Callable&lt;String&gt;()
{
@Override
public String call() throws Exception
{
String t2 = method2();
return t2;
}
};
Callable&lt;String&gt; callable3 = new Callable&lt;String&gt;()
{
@Override
public String call() throws Exception
{
String t3 = method3();
return t3;
}
};
List&lt;Callable&lt;String&gt;&gt; taskList = new ArrayList&lt;Callable&lt;String&gt;&gt;();
taskList.add(callable1);
taskList.add(callable2);
taskList.add(callable3);
ExecutorService executor = Executors.newFixedThreadPool(3);
try
{
executor.invokeAll(taskList);
//total = ;(want to concatenate all the strings here).
System.out.println(total);
}
catch (InterruptedException ie)
{
//do something if you care about interruption;
}
}
public static String method1()
{
System.out.println(&quot;method1&quot;);
return &quot;1&quot;;
}
private static String method2()
{
System.out.println(&quot;method2&quot;);
return &quot;2&quot;;
}
private static String method3()
{
System.out.println(&quot;method3&quot;);
return &quot;3&quot;;
}
}

答案1

得分: 1

taskList是一个List&lt;Callable&lt;String&gt;&gt;executor.invokeAll(taskList)会返回一个包含与taskList中每个任务对应的Future&lt;String&gt;List&lt;Future&lt;String&gt;&gt;。您需要保存该List&lt;Future&lt;String&gt;&gt;,以便以后可以获取任务的结果。类似这样:

List&lt;Future&lt;String&gt;&gt; futureList = executor.invokeAll(tasklist);
String result = futureList.get(0).get() +
                futureList.get(1).get() +
                futureList.get(2).get();

除了InterruptedException之外,Future.get()还可能抛出CancellationExceptionExecutionException,因此您需要在try块中处理这些异常。

英文:

As taskList is a List&lt;Callable&lt;String&gt;&gt;, executor.invokeAll(taskList) returns a List&lt;Future&lt;String&gt;&gt; containing a Future&lt;String&gt; corresponding to each task in taskList. You need to save that List&lt;Future&lt;String&gt;&gt; so that you can later get at the results of your tasks. Something like this:

List&lt;Future&lt;String&gt;&gt; futureList = executor.invokeAll(tasklist);
String result = futureList.get(0).get() +
futureList.get(1).get() +
futureList.get(2).get();

In addition to InterruptedException, Future.get() can also throw CancellationException and ExecutionException so you need to be prepared to deal with these in your try block.

答案2

得分: 0

由于您只需要代码部分的翻译,以下是您提供的代码的中文翻译:

由于您的任务数量很少您可以创建3个`CompletableFuture`,并在流中对其进行处理后合并

    CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> method1());
    CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> method2());
    CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> method3());
 
    String concate = Stream.of(task1, task2, task3)
            .map(CompletableFuture::join)
            .reduce("", (s1, s2) -> s1 + s2);
    System.out.println(concate);
英文:

As you have very few number of task, you can create 3 CompletableFutures and stream over it and join it.

CompletableFuture&lt;String&gt; task1 = CompletableFuture.supplyAsync(() -&gt; method1());
CompletableFuture&lt;String&gt; task2 = CompletableFuture.supplyAsync(() -&gt; method2());
CompletableFuture&lt;String&gt; task3 = CompletableFuture.supplyAsync(() -&gt; method3());
String concate = Stream.of(task1, task2, task3)
.map(CompletableFuture::join)
.reduce(&quot;&quot;, (s1, s2) -&gt; s1 + s2);
System.out.println(concate);

答案3

得分: 0

在 @Govinda 的回答基础上,您可以通过使用 supplyAsync 工厂方法创建一组 CompletableFutureStream,然后通过调用 CompletableFuture::join 来完成它们,最后使用 Collectors.joining() 进行连接。

CompletableFuture<String> task1 = CompletableFuture.supplyAsync(Test::method1);
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(Test::method2);
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(Test::method3);

String concat =
    Stream.of(task1, task2, task3).map(CompletableFuture::join).collect(Collectors.joining());

System.out.println(concat);
英文:

Adding on top of @Govinda answer -
You can create Stream of CompletableFutures by using the supplyAsync factory method and complete them by calling CompletableFuture::join and concat by calling Collectors.joining().

CompletableFuture&lt;String&gt; task1 = CompletableFuture.supplyAsync(Test::method1);      
CompletableFuture&lt;String&gt; task2 = CompletableFuture.supplyAsync(Test::method2);      
CompletableFuture&lt;String&gt; task3 = CompletableFuture.supplyAsync(Test::method3);      
String concat =                                                                               
Stream.of(task1, task2, task3).map(CompletableFuture::join).collect(Collectors.joining());
System.out.println(concat);  

huangapple
  • 本文由 发表于 2020年8月16日 13:45:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63433545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定