1.简介
CompletableFuture 是 JDK8 提供的一个异步执行工具。
示例1:
public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { for (int i = 0; i < 3; i++) { System.out.println(i); try { Thread.sleep(1000L); } catch (InterruptedException ignored) { } } System.out.println("Future Finished."); }); System.out.println("Main Thread Finished."); future.get(); }
输出结果1:
2.异步执行
CompletableFuture 提供了两个方法用于异步执行:
CompletableFuture.runAsync,
没有返回值
;
CompletableFuture.supplyAsync,
有返回值
。
示例:
public static void main(String[] args) throws ExecutionException, InterruptedException { // runAsync 没有返回值 CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("future1 executed.")); // supplyAsync 有返回值 CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> { System.out.println("future2 executed."); return "result"; }); System.out.println("future1.get(): " + future1.get()); System.out.println("future2.get(): " + future2.get()); }
输出结果:
3.守护线程
CompletableFuture返回的Future默认为守护线程
,如果不调用get()获取结果,主线程结束后会自动结束
。主要有以下4种情景:
- 情景1: 执行时间 > 主线程时间,异步线程
会执行
; - 情景2: 执行时间 > 主线程,是守护线程,会被杀死,异步线程
不会执行
; - 情景3: 执行时间 > 主线程,但是不是守护线程,不会被杀死,异步线程
会执行
; - 情景4: ExecutorService.submit(),默认不是守护线程,不会被杀死,异步线程
会执行
。
示例:
public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); // 1.执行时间 < 主线程,会打印 CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("Thread1 是否为守护线程 : " + Thread.currentThread().isDaemon())); // 2.执行时间 > 主线程,是守护线程,会被杀死,不会打印 CompletableFuture.runAsync(() -> { try { Thread.sleep(3000L); S<i>本文来源gaodai$ma#com搞$$代**码)网@</i>ystem.out.println("Thread2 是否为守护线程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}); // 3.执行时间 > 主线程,但是不是守护线程,不会被杀死,会打印 CompletableFuture.runAsync(() -> { try { Thread.sleep(1000L); System.out.println("Thread3 等待1秒"); System.out.println("Thread3 是否为守护线程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}, executorService); // 4.ExecutorService.submit(),默认不是守护线程,不会被杀死,会打印。 executorService.submit(() -> { try { Thread.sleep(2000L); System.out.println("Thread4 等待2秒"); System.out.println("Thread4 是否为守护线程 : " + Thread.currentThread().isDaemon()); } catch (InterruptedException e) { e.printStackTrace(); }}); // 主线程执行完毕 System.out.println("Main Thread Finished."); executorService.shutdown(); }