Java 多次可运行完成后返回值

Java 多次可运行完成后返回值,java,multithreading,runnable,Java,Multithreading,Runnable,目前我有一个代码如下: public String getValue() { StringBuilder builder = new StringBuilder(); // 1st step //some logic to retreive code from database returning value //doing something with the returned value add it to collection builder.append(s

目前我有一个代码如下:

public String getValue()
{
   StringBuilder builder = new StringBuilder();
   // 1st step
   //some logic to retreive code from database returning value
   //doing something with the returned value add it to collection
   builder.append(someString1);
   // 2nd step
   //some logic to retreive code from database returning value
   //doing something with the returned value add it to collection
   builder.append(someString2);
   // 3rd step
   //some logic to retreive code from database returning value
   //doing something with the returned value add it to collection
   builder.append(someString3);

   return builder.toString();
}
我读过关于Runnable对象的内容,它可以用来将进程拆分为多个线程,从而将我的代码更改为如下内容:

public String getValue()
{
     Thread firstTread = new Thread(new Process1());
     firstTread.start();
     Thread secondTread = new Thread(new Process1());
     secondTread.start();
     Thread thirdTread = new Thread(new Process1());
     thirdTread.start();

     // here i got confuse how to determine whether all thread allready finished 
     // before returning builder.toString();
}
//this is internal class
class Process1 implements Runnable
{
    public void run()
    {
      //do something and add to StringBuilder
    }
}

class Process2 implements Runnable
{
    public void run()
    {
      //do something and add to StringBuilder
    }
}

class Process3 implements Runnable
{
    public void run()
    {
      //do something and add to StringBuilder
    }
}

如何实现将进程拆分为多个线程的目标?

您使用
Callable
,它基本上是一个
Runnable
返回值。您可以使用
ExecutorService
,而不是自己创建
Thread
对象

public String getValue()
{
    ExecutorService threaded = Executors.newFixedThreadPool(NUM_THREADS);
    List<CompletableFuture> results = threaded.invokeAll(
        Arrays.asList(this::process1, this::process2, this::process3);
    results.stream()
        .map(Future::get)  // collects the result from each thread
        .collect(Collectors.joining());
}
private String process1() { return "1"; }
private String process2() { return "2"; }
private String process3() { return "3"; }
公共字符串getValue()
{
ExecutorService threaded=Executors.newFixedThreadPool(NUM_线程);
列表结果=threaded.invokeAll(
asList(this::process1、this::process2、this::process3);
结果.流()
.map(Future::get)//从每个线程收集结果
.collect(收集器.joining());
}
私有字符串process1(){return“1”;}
私有字符串process2(){return“2”;}
私有字符串process3(){return“3”;}
编辑:
请注意,输出不会“以不同的顺序”,因为。

您使用
Callable
,这基本上是一个
Runnable
返回值。并且您使用
ExecutorService
而不是自己创建
线程
对象

public String getValue()
{
    ExecutorService threaded = Executors.newFixedThreadPool(NUM_THREADS);
    List<CompletableFuture> results = threaded.invokeAll(
        Arrays.asList(this::process1, this::process2, this::process3);
    results.stream()
        .map(Future::get)  // collects the result from each thread
        .collect(Collectors.joining());
}
private String process1() { return "1"; }
private String process2() { return "2"; }
private String process3() { return "3"; }
公共字符串getValue()
{
ExecutorService threaded=Executors.newFixedThreadPool(NUM_线程);
列表结果=threaded.invokeAll(
asList(this::process1、this::process2、this::process3);
结果.流()
.map(Future::get)//从每个线程收集结果
.collect(收集器.joining());
}
私有字符串process1(){return“1”;}
私有字符串process2(){return“2”;}
私有字符串process3(){return“3”;}
编辑:
请注意,输出不会“以不同的顺序”进行,因为并行工作还有其他选择,但要回答如何等待线程完成的直接问题,可以使用

firstTread.join();
secondTread.join();
thirdTread.join();

并行化工作还有其他选择,但要回答如何等待线程完成的直接问题,可以使用

firstTread.join();
secondTread.join();
thirdTread.join();

Callable
更适合此类任务,因为它返回结果

ExecutorService
有助于加强线程管理

  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    List<Future<String>> futures = new ArrayList<>();
    futures.add(executorService.submit(new Process1()));
    futures.add(executorService.submit(new Process2()));
    futures.add(executorService.submit(new Process3()));

    StringBuilder sb = new StringBuilder();
    for (Future<String> future : futures) {
      // handle exceptions
      sb.append(future.get());
    }
  }
publicstaticvoidmain(字符串[]args)引发异常{
ExecutorService ExecutorService=Executors.newFixedThreadPool(3);
列表期货=新的ArrayList();
futures.add(executorService.submit(newprocess1());
futures.add(executorService.submit(newprocess2());
futures.add(executorService.submit(newprocess3());
StringBuilder sb=新的StringBuilder();
for(未来:未来){
//处理异常
sb.append(future.get());
}
}

可调用的
更适合此类任务,因为它返回结果

ExecutorService
有助于加强线程管理

  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    List<Future<String>> futures = new ArrayList<>();
    futures.add(executorService.submit(new Process1()));
    futures.add(executorService.submit(new Process2()));
    futures.add(executorService.submit(new Process3()));

    StringBuilder sb = new StringBuilder();
    for (Future<String> future : futures) {
      // handle exceptions
      sb.append(future.get());
    }
  }
publicstaticvoidmain(字符串[]args)引发异常{
ExecutorService ExecutorService=Executors.newFixedThreadPool(3);
列表期货=新的ArrayList();
futures.add(executorService.submit(newprocess1());
futures.add(executorService.submit(newprocess2());
futures.add(executorService.submit(newprocess3());
StringBuilder sb=新的StringBuilder();
for(未来:未来){
//处理异常
sb.append(future.get());
}
}

您要查找的不是Runnable,而是一个。与Runnable不同,Callable返回一个值。这通常与(线程池)一起使用

在线程池中维护线程总是好的,而不是像那样手动生成线程。这可以防止不必要且昂贵的线程创建。其思想是,不要调用
thread.start()
,您可以使用预定义的线程数将
可调用的
实例提交给
ExecutorService
实例。每次提交都会返回一个对象。Future object允许您等待已提交给ExecutorService的可调用实例的返回值

以下是原始代码的修订版本:

class Process1 implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "Some string from this callable";
    }
}
// Insert implementation for Process2 and Process2 Callables
   ...

public static void main(String[] args) throws Exception {
   ExecutorService executor = Executors.newFixedThreadPool(3);

   Future<String> process1Future = executor.submit(new Process1());
   Future<String> process2Future = executor.submit(new Process2());
   Future<String> process3Future = executor.submit(new Process3());

   // It will wait here 
   String processedStringByProcess1 = process1Future.get();
   String processedStringByProcess2 = process2Future.get();
   String processedStringByProcess3 = process3Future.get();

   StringBuilder builder = new StringBuilder();
   builder.append(processedStringByProcess1);
   builder.append(processedStringByProcess2);
   builder.append(processedStringByProcess3);

   System.out.println(builder.toString());
}
类Process1实现可调用{
@凌驾
公共字符串调用()引发异常{
返回“此可调用函数中的某些字符串”;
}
}
//插入Process2和Process2可调用项的实现
...
公共静态void main(字符串[]args)引发异常{
ExecutorService executor=Executors.newFixedThreadPool(3);
Future process1Future=executor.submit(新流程1());
Future process2Future=executor.submit(new Process2());
Future process3Future=executor.submit(new Process3());
//它会在这里等着
String processedStringByProcess1=process1Future.get();
String processedStringByProcess2=process2Future.get();
String processedStringByProcess3=process3Future.get();
StringBuilder=新的StringBuilder();
append(processedStringByProcess1);
append(processedStringByProcess2);
append(processedStringByProcess3);
System.out.println(builder.toString());
}

您要查找的不是Runnable,而是一个。与Runnable不同,Callable返回一个值。这通常与(线程池)一起使用

在线程池中维护线程总是好的,而不是像那样手动生成线程。这可以防止不必要且昂贵的线程创建。其思想是,不要调用
thread.start()
,您可以使用预定义的线程数将
可调用的
实例提交给
ExecutorService
实例。每次提交都会返回一个对象。Future object允许您等待已提交给ExecutorService的可调用实例的返回值

以下是原始代码的修订版本:

class Process1 implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "Some string from this callable";
    }
}
// Insert implementation for Process2 and Process2 Callables
   ...

public static void main(String[] args) throws Exception {
   ExecutorService executor = Executors.newFixedThreadPool(3);

   Future<String> process1Future = executor.submit(new Process1());
   Future<String> process2Future = executor.submit(new Process2());
   Future<String> process3Future = executor.submit(new Process3());

   // It will wait here 
   String processedStringByProcess1 = process1Future.get();
   String processedStringByProcess2 = process2Future.get();
   String processedStringByProcess3 = process3Future.get();

   StringBuilder builder = new StringBuilder();
   builder.append(processedStringByProcess1);
   builder.append(processedStringByProcess2);
   builder.append(processedStringByProcess3);

   System.out.println(builder.toString());
}
类Process1实现可调用{
@凌驾
公共字符串调用()引发异常{