将 Future 与 ExecutorService 结合使用
Using Future with 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
来自 get
javadoc:
Waits if necessary for the computation to complete, and then retrieves its result.
get
只会等待第二个任务。
来自 awaitTermination
javadoc:
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
awaitTermination
将等待所有任务。
你应该使用 CompletableFuture
API
您可以 运行 如下所示的异步进程:
CompletableFuture.supplyAsync( () -> { ... } );
它 returns 一个未来,你可以添加一个回调,当进程完成并且结果可用时调用。
例如:
CompletableFuture.runAsync( () -> {
// Here compute your string
return "something";
} ).thenAccept( result -> {
// Here do something with result (ie the computed string)
} );
请注意,此语句在内部使用 ForkJoinPool#commonPool()
来执行进程异步,但如果需要,您也可以使用自己的 ExecutorService
调用此语句。在这两种情况下,为了确保在任务完成之前不退出,您需要在每个提交任务的未来调用 get()
(阻塞),或者等待执行程序关闭。
我需要并行执行两个任务并等待它们完成。我还需要第二个任务的结果,因为我正在使用 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
来自 get
javadoc:
Waits if necessary for the computation to complete, and then retrieves its result.
get
只会等待第二个任务。
来自 awaitTermination
javadoc:
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
awaitTermination
将等待所有任务。
你应该使用 CompletableFuture
API
您可以 运行 如下所示的异步进程:
CompletableFuture.supplyAsync( () -> { ... } );
它 returns 一个未来,你可以添加一个回调,当进程完成并且结果可用时调用。
例如:
CompletableFuture.runAsync( () -> {
// Here compute your string
return "something";
} ).thenAccept( result -> {
// Here do something with result (ie the computed string)
} );
请注意,此语句在内部使用 ForkJoinPool#commonPool()
来执行进程异步,但如果需要,您也可以使用自己的 ExecutorService
调用此语句。在这两种情况下,为了确保在任务完成之前不退出,您需要在每个提交任务的未来调用 get()
(阻塞),或者等待执行程序关闭。