Origin of CompletableFuture
CompletableFuture implements the CompletionStage interface, which is an extension of the Future interface. It adds asynchronous callbacks, streaming processing, and the ability to combine multiple Futures to make Java easier to handle multitask collaborative work.
Code examples (1)
thenCombine
public class Futrue { public static void main(String[] args) { System.out.println("Xiao Fan has come to the dining room"); System.out.println("Xiao Fan ordered scrambled eggs with tomatoes+ A bowl of rice"); CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> { System.out.println("The cook started cooking"); work(5); return "Fried eggs with tomatoes"; }).thenCombine(CompletableFuture.supplyAsync(() -> { System.out.println("The waiter starts steaming rice"); work(2); return "Steamed Rice"; }), (food1, food2) -> { return food1 + food1; }); System.out.println("Xiao Fan starts by playing a game and waiting for the meal to be ready"); System.out.println(data.join()+"The rice is ready. Xiao Fan starts eating"); System.out.println("My meal"); } //Start Work Time: Work hours public static void work(Integer workTime) { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
Xiao Fan has come to the dining room
Xiao Fan ordered scrambled tomato eggs + a bowl of rice
The cook started cooking
The waiter starts steaming rice
Xiao Fan starts by playing a game and waiting for the meal to be ready
The waiter steamed the rice
The cook has finished cooking
Scrambled tomato and egg rice are ready. Xiao Fan starts eating
My meal
Here we find that the cook's stir-frying and the server's steaming are done at the same time, and finally merge the results of the two threads and return
Code examples (2)
thenCompose
public class Futrue { public static void main(String[] args) { System.out.println("Xiao Fan has come to the dining room"); System.out.println("Xiao Fan ordered scrambled eggs with tomatoes+ A bowl of rice"); CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> { System.out.println("The cook started cooking"); work(5); System.out.println("Chef's stir-frying done"); return "Fried eggs with tomatoes"; }).thenCompose(dish -> CompletableFuture.supplyAsync(() -> { System.out.println("The waiter starts to serve"); work(2); System.out.println("The waiter finished the dish"); return dish + "Steamed Rice"; })); System.out.println("Xiao Fan starts by playing a game and waiting for the meal to be ready"); System.out.println(data.join()+"The rice is ready. Xiao Fan starts eating"); System.out.println("My meal"); } //Start Work Time: Work hours public static void work(Integer workTime) { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
Xiao Fan has come to the dining room
Xiao Fan ordered scrambled tomato eggs + a bowl of rice
The cook started cooking
Xiao Fan starts by playing a game and waiting for the meal to be ready
Chef's stir-frying done
The waiter starts to serve
The waiter finished the dish
Scrambled egg with tomatoes and rice are ready. Xiao Fan starts eating
My meal
Here we will start with the chef's stir-frying and the server's steaming the rice in sequence. At last, the waiter will serve the food and the rice to the guests.
Code Sample (3)
The nApply and the nCompose are very similar
public class Futrue { public static void main(String[] args) { System.out.println("Xiao Fan has finished eating"); System.out.println("Xiaofan checkout, invoice required"); //Scenario: The same person is required for payment and invoice CompletableFuture<String> data = CompletableFuture.supplyAsync(() -> { System.out.println("Waiter" + Thread.currentThread().getName() + "Receipt 500"); work(5); System.out.println("Waiter" + Thread.currentThread().getName() + "Payment Received"); return "500"; }).thenApply(money -> { System.out.println("Invoicer" + Thread.currentThread().getName() + "open an account with"+money+"Size Invoice"); work(5); System.out.println("Invoicer" + Thread.currentThread().getName() + "Ended Invoicing"); return "500 Yuan Invoice"; }); System.out.println("Xiao Fan answered the phone and was ready to go home to play games"); System.out.println(data.join() + "It's ready."); System.out.println("Xiao Fan goes home"); } //Start Work Time: Work hours public static void work(Integer workTime) { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
Xiao Fan has finished eating
Xiaofan checkout, invoice required
Server ForkJoinPool.commonPool-worker-9 Collection 500
Xiao Fan answered the phone and was ready to go home to play games
Server ForkJoinPool.commonPool-worker-9 Collection
Invoicer ForkJoinPool.commonPool-worker-9 invoiced 500 sizes
Invoicer ForkJoinPool.commonPool-worker-9 has finished Invoicing
500 yuan invoice ready.
Xiao Fan is ready to go home
Code Samples (IV)
applyToEither: Gets the fastest executing asynchronous method and returns the result
public class Futrue { public static void main(String[] args) { System.out.println("Xiao Fan left the canteen to the bus stop"); System.out.println("Waiting for No. 1 or No. 2 cars"); CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("1 Road cars are coming"); work(5); return "1 Road Cars"; }).applyToEither(CompletableFuture.supplyAsync(() -> { System.out.println("2 Road cars are coming"); work(10); return "2 Road Cars"; }), fisrtMethod -> fisrtMethod); System.out.println(completableFuture.join()+"Cars come first, get home"); } //Start Work Time: Work hours public static void work(Integer workTime) { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
Xiao Fan left the canteen to the bus stop
Waiting for No. 1 or No. 2 cars
No.1 bus is coming
No. 2 bus is coming
Car No.1 Comes first and gets home
Sample Code (5)
exceptionally: asynchronous programming exception handling
public class Futrue { public static void main(String[] args) { System.out.println("Xiao Fan left the canteen to the bus stop"); System.out.println("Waiting for No. 1 or No. 2 cars"); CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println("1 Road cars are coming"); work(5); return "1 Road Cars"; }).applyToEither(CompletableFuture.supplyAsync(() -> { System.out.println("2 Road cars are coming"); work(10); return "2 Road Cars"; }), fisrtMethod -> { if (fisrtMethod.equals("1 Road Cars")) { throw new RuntimeException("Hit a tree"); } return fisrtMethod; }).exceptionally(e -> { System.out.println(e.getMessage()); System.out.println("Xiao Bai called out the taxi to go home"); return "Taxi"; }); System.out.println(completableFuture.join() + "Cars come first, get home"); } //Start Work Time: Work hours public static void work(Integer workTime) { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
Xiao Fan left the canteen to the bus stop
Waiting for No. 1 or No. 2 cars
No.1 bus is coming
No. 2 bus is coming
java.lang.RuntimeException: hit a tree
Xiao Bai called out the taxi to go home
Taxi comes first, get home