使用Future与ExecutorService

时间:2016-01-14 15:32:31

标签: java multithreading java-8 executorservice

我需要并行执行两个任务并等待它们完成。此外,我需要第二个任务的结果,因为我正在使用Future

我的问题是我需要executor.awaitTermination加入任务吗?Future.get()会照顾它。还有一种更好的方法来实现Java 8吗?

public class Test {

    public static void main(String[] args) {
        test();
        System.out.println("Exiting Main");
    }

    public static void test() {
        System.out.println("In Test");
        ExecutorService executor = Executors.newFixedThreadPool(2);

        executor.submit(() -> {
            for(int i = 0 ; i< 5 ; i++) {
                System.out.print("["+i+"]");
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {e.printStackTrace();}
            }
        });

        Future<String> result = executor.submit(() -> {
            StringBuilder builder = new StringBuilder();
            for(int i = 0 ; i< 10 ; i++) {
                System.out.print("("+i+")");
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {e.printStackTrace();}
                builder.append(i);
            }
            return builder.toString();
        });

        System.out.println("shutdown");
        executor.shutdown();
        // DO I need this code : START
        System.out.println("awaitTermination");
        try {
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            System.out.println("Error");
        }
        // DO I need this code : END
        System.out.println("Getting result");
        try {
            System.out.println(result.get());
        } 
        catch (InterruptedException e) {e.printStackTrace();} 
        catch (ExecutionException e) {e.printStackTrace();}
        System.out.println("Exiting Test");
    }

}

输出 awaitTermination

In Test
[0]shutdown
(0)awaitTermination
[1](1)[2](2)[3](3)[4](4)(5)(6)(7)(8)(9)Getting result
0123456789
Exiting Test
Exiting Main

没有 awaitTermination的输出

In Test
[0]shutdown
Getting result
(0)[1](1)[2](2)[3](3)[4](4)(5)(6)(7)(8)(9)0123456789
Exiting Test
Exiting Main

2 个答案:

答案 0 :(得分:3)

来自get javadoc:

  

如果需要等待计算完成,然后检索其结果。

get将仅等待第二项任务。

来自awaitTermination javadoc:

  

阻止所有任务在关闭请求之后完成执行,或发生超时,或者当前线程被中断,以先发生者为准。

awaitTermination将等待所有任务。

答案 1 :(得分:0)

您应该使用CompletableFuture API

您可以像以下一样运行异步处理:

CompletableFuture.supplyAsync( () -> { ... } );

它返回一个未来,你可以添加一个回调,当进程完成并且结果可用时将调用它。

例如:

CompletableFuture.runAsync( () -> { 
     // Here compute your string
     return "something";
} ).thenAccept( result -> {
     // Here do something with result (ie the computed string)
} );

请注意,此语句在内部使用ForkJoinPool#commonPool()来执行进程异步,但如果需要,您也可以使用自己的ExecutorService调用此语句。在这两种情况下,为了确保在任务完成之前不退出,您需要在提交的任务的每个未来调用get()(阻塞),或者等待执行程序关闭。