Tech Master Tutorials
Email Facebook Google LinkedIn Pinterest Twitter
Home Java Java 8 Java Interview Questions Java8 Interview Questions Object Oriented Programming in Java JVM Java Programming

CompletableFuture - Java Async Programming

Prior to understanding execution of completion stages, good to have knowledge on the below
Methods used in the below examples of serial execution of the completablefutures:
  • thenAccept(): Accept the result of the CompletionStage, and computation passed inside the method completes, then return a CompletionStage of void type.
  • anyOf() : Returns the CompletableFuture of Void type once any of the completable future from the list is completed
  • allOf() : Returns the CompletableFuture of Void type once all of the completable futures from the list are completed
  • completedFuture(): Returns a completed CompletableFuture wrapped with the passed value to the method.



Executing Completable Futures in Parallel : return after all of the futures complete

package completables;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

public class CompletableFuture_Parallel {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		CompletableFuture_Parallel completableFuturesSerialExecution
														 = new CompletableFuture_Parallel();
		completableFuturesSerialExecution.executeCompletableFuturesInParallel();
	}

	private void executeCompletableFuturesInParallel() throws InterruptedException, ExecutionException {
		List<CompletableFuture<String>> completableFutures = new ArrayList<>();
		TaskImpl task = new TaskImpl();
		for (int i = 0; i < 5; i++) {
			CompletableFuture<String> completableFuture = executeRule(i, task);
			completableFutures.add(completableFuture);
		}

		CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]))
		.thenAccept(__ -> System.out.println("All futures completed successfully"));
	}

	private CompletableFuture<String> executeRule(int i, TaskImpl customRuleNumber) 
													throws InterruptedException, ExecutionException {
		return customRuleNumber.executeTask(i);

	}

	abstract class Task {
		abstract CompletionStage<String> executeTask(int n);
	}

	class TaskImpl extends Task {
		CompletableFuture<String> executeTask(int n) {
			System.out.println("Executing Task number = " + n);
			return CompletableFuture.completedFuture("" + n);
		};
	}

}


Output:
Executing Task number = 0
Executing Task number = 1
Executing Task number = 2
Executing Task number = 3
Executing Task number = 4
All futures completed successfully



Executing Completable Futures in Parallel : return after any of the futures complete

package completables;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

public class CompletableFuture_Parallel_anyOf {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		CompletableFuture_Parallel_anyOf completableFuturesSerialExecution
																 = new CompletableFuture_Parallel_anyOf();
		completableFuturesSerialExecution.executeCompletableFuturesInParallel();
	}

	private void executeCompletableFuturesInParallel() throws InterruptedException, ExecutionException {
		List<CompletableFuture<String>> completableFutures = new ArrayList<>();
		TaskImpl task = new TaskImpl();
		for (int i = 0; i < 5; i++) {
			CompletableFuture<String> completableFuture = executeRule(i, task);
			completableFutures.add(completableFuture);
		}

		CompletableFuture.anyOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]))
		.thenAccept(__ -> System.out.println("Future(Optionally others also) completed successfully"));
	}

	private CompletableFuture<String> executeRule(int i, TaskImpl customRuleNumber) 
													throws InterruptedException, ExecutionException {
		return customRuleNumber.executeTask(i);

	}

	abstract class Task {
		abstract CompletionStage<String> executeTask(int n);
	}

	class TaskImpl extends Task {
		CompletableFuture<String> executeTask(int n) {
			System.out.println("Executing Task number = " + n);
			return CompletableFuture.completedFuture("" + n);
		};
	}

}


Output:
Executing Task number = 0
Executing Task number = 1
Executing Task number = 2
Executing Task number = 3
Executing Task number = 4
Future(Optionally others also) completed successfully