一、CompletableFuture用法入门介绍
入门介绍的一个例子:
1 package com.cy.java8; 2 3 import java.util.Random; 4 import java.util.concurrent.CompletableFuture; 5 6 public class CompletableFutureInAction { 7 private final static Random RANDOM = new Random(System.currentTimeMillis()); 8 9 public static void main(String[] args){ 10 CompletableFuture<Double> completableFuture = new CompletableFuture<>(); 11 new Thread(() -> { 12 double value = get(); 13 completableFuture.complete(value); 14 }).start(); 15 16 System.out.println("do other things..."); 17 18 completableFuture.whenComplete((t, e) -> { 19 System.out.println("complete. value = "+ t); 20 if(e != null){ 21 e.printStackTrace(); 22 } 23 }); 24 } 25 26 private static double get(){ 27 try { 28 Thread.sleep(RANDOM.nextInt(3000)); 29 } catch (InterruptedException e) { 30 e.printStackTrace(); 31 } 32 return RANDOM.nextDouble(); 33 } 34 }
console打印:
do other things... complete. value = 0.8244376567363494
二、CompletableFuture.supplyAsync
CompletableFuture很少有直接new出来的方式去用的,一般都是通过提供的静态方法来使用。
1.使用CompletableFuture.supplyAsync来构造CompletableFuture:
1 package com.cy.java8; 2 3 import java.util.concurrent.*; 4 5 import static com.cy.java8.CompletableFutureInAction.get; 6 7 public class CompletableFutureInAction2 { 8 9 public static void main(String[] args) { 10 /** 11 * 可以发现value=..没有被打印,为什么呢? 12 * 因为此方法构造出来的线程是demon的,守护进程,main执行结束之后就消失了,所以 13 * 根本没来得及执行whenComplete中的语句 14 */ 15 CompletableFuture.supplyAsync(() -> get()) 16 .whenComplete((v, e) -> { 17 System.out.println("value = " + v); 18 if (e != null) { 19 e.printStackTrace(); 20 } 21 }); 22 23 System.out.println("do other things..."); 24 } 25 26 27 }
2.要将上面whenComplete中的语句执行,进行改造:
1 package com.cy.java8; 2 3 import java.util.concurrent.*; 4 import java.util.concurrent.atomic.AtomicBoolean; 5 import static com.cy.java8.CompletableFutureInAction.get; 6 7 public class CompletableFutureInAction2 { 8 9 public static void main(String[] args) throws InterruptedException { 10 AtomicBoolean finished = new AtomicBoolean(false); 11 12 CompletableFuture.supplyAsync(() -> get()) 13 .whenComplete((v, e) -> { 14 System.out.println("value = " + v); 15 if (e != null) { 16 e.printStackTrace(); 17 } 18 finished.set(true); 19 }); 20 21 System.out.println("do other things..."); 22 23 while(!finished.get()){ 24 Thread.sleep(1); 25 } 26 } 27 28 29 }
改写之后, main线程发现如果finished没有变为true就会一直等1ms,直到whenComplete执行将finished变为true。
3.上面的改写很low,其实只要将守护线程变为前台进程,main结束后不会消失就行了。
1 package com.cy.java8; 2 3 import java.util.concurrent.*; 4 import static com.cy.java8.CompletableFutureInAction.get; 5 6 public class CompletableFutureInAction2 { 7 8 public static void main(String[] args){ 9 ExecutorService executorService = Executors.newFixedThreadPool(2, r -> { 10 Thread t = new Thread(r); 11 t.setDaemon(false); //非守护线程 12 return t; 13 }); 14 15 CompletableFuture.supplyAsync(() -> get(), executorService) 16 .whenComplete((v, e) -> { 17 System.out.println("value = " + v); 18 if (e != null) { 19 e.printStackTrace(); 20 } 21 }); 22 23 System.out.println("do other things..."); 24 25 //main执行结束之后,executorService线程不会结束,需要手动shutdown 26 executorService.shutdown(); 27 } 28 29 30 }
三、
----
原文地址:https://www.cnblogs.com/tenWood/p/11614336.html
时间: 2024-11-23 17:20:03