CompletableFuture 常用方法小抄

关于 CompletableFuture, 引用 baeldung 中的一句话:

The best part of the CompletableFuture API is the ability to combine CompletableFuture instances in a chain of computation steps.

本文整理了 CompletableFuture 一些常用的方法,方便日后需要的时候查看。

回调

/**
 * 总结:
 * run:没参数传递,没返回值
 * accept:有参数传递,没返回值
 * apply:有参数传递,有返回值
 *
 * @author LBG - 2022/12/3
 */
public class CompletableFutureDemo {

	public static void main(String[] args) throws Exception {
		//runAsync();
		//supplyAsync();

		//thenRun();

		//thenAccept();

		//thenApply();

		//exceptionally();

		//whenComplete();

		 handle();

		Thread.sleep(1000L);
	}

	/****************** 创建异步任务 ******************/

	/**
	 * 创建一个无返回值的异步任务
	 */
	private static void runAsync() {
		CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("runAsync demo"));
	}

	/**
	 * 创建一个有返回值的异步任务
	 */
	private static void supplyAsync() throws Exception {
		CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> "has return value");
		System.out.println(supplyAsync.get());
	}

	/****************** 异步任务完成后回调(没有参数传递,没有返回值) ******************/

	/**
	 * 两个任务之间没有参数传递,且没有返回值
	 */
	private static void thenRun() {
		CompletableFuture<Void> voidFuture =
				CompletableFuture.supplyAsync(() -> "return value is thenRun")
						.thenRun(() -> System.out.println("then run"));
	}

	/**
	 * 和 thenRun 的区别就是 thenRunAsync 可以传入自定义线程池
	 */
	private static void thenRunAsync() {
		CompletableFuture<Void> voidFuture =
				CompletableFuture.supplyAsync(() -> "return value is thenRunAsync")
						.thenRunAsync(() -> System.out.println("thenRunAsync"));
	}

	/****************** 异步任务完成后回调(有参数传递,没有返回值) ******************/

	/**
	 * 两个任务之间有参数传递,没有返回值
	 */
	private static void thenAccept() {
		// thenAccept thenAcceptAsync 区别:后者可以传入线程池
		CompletableFuture<Void> voidFuture =
				CompletableFuture.supplyAsync(() -> "thenAccept value")
						.thenAccept((value) -> System.out.println("previous value is " + value));

		//ExecutorService pool = Executors.newFixedThreadPool(1);
		//CompletableFuture<Void> voidFuture =
		//		CompletableFuture.supplyAsync(() -> "thenAccept value")
		//				.thenAcceptAsync((value) -> System.out.println("previous value is " + value), pool);
	}

	/****************** 异步任务完成后回调(有参数传递,有返回值) ******************/

	/*
	 * 两个任务之间有参数传递,回调有返回值
	 */
	private static void thenApply() throws Exception {
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "one").thenApply((value) -> value + " two");
		System.out.println(future.get());

		//CompletableFuture<String> future = CompletableFuture
		//		.supplyAsync(() -> "one")
		//		.thenApplyAsync((value) -> value + " two", Executors.newFixedThreadPool(1));
		//System.out.println(future.get());
	}

	/****************** 任务异常 ******************/

	private static void exceptionally() throws Exception {
		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
			int num = RandomUtils.nextInt(1, 10);
			if (num < 6) {
				throw new RuntimeException("exceptionally num " + num);
			}
			return num;
		});

		future.exceptionally((e) -> {
			e.printStackTrace();
			return null;
		});

		System.out.println(future.get());
	}

	/****************** 某个任务执行完成后,执行的回调方法,无返回值 ******************/

	private static void whenComplete() throws Exception {
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "task value")
				.whenComplete((val, e) -> System.out.println("task complete " + val));
		System.out.println(future.get()); // 返回的是任务的返回值,不是 whenComplete
	}

	/****************** 某个任务执行完成后,执行的回调方法,返回值是任务的返回值 ******************/

	/**
	 * 任务执行完的回调,有自己的返回值
	 */
	private static void handle() throws Exception {
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "handle value")
				.handle((val, throwable) -> val + " handle");
		System.out.println(future.get());
	}
}

组合

public class CompletableFutureCombineDemo {

	public static void main(String[] args) throws Exception {
		// AND
		//thenCombine();
		//thenAcceptBoth();
		// runAfterBoth();

		// OR
		//applyToEither();
		//acceptEither();
		//runAfterEither();

		//allOf();
		anyOf();
	}

	/****************** AND 两个任务都执行完后执行 ******************/

	/**
	 * 两个任务的结果作为方法入参,且有返回值
	 */
	private static void thenCombine() throws Exception  {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> "one");
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> "two");

		CompletableFuture<String> threeFuture = twoFuture.thenCombine(oneFuture, (two, one) -> {
			System.out.println(one);
			System.out.println(two);
			return "three";
		});

		System.out.println(threeFuture.get());
	}

	/**
	 * 两个任务的结果作为方法入参,无返回值
	 */
	private static void thenAcceptBoth() throws Exception {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> "one");
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> "two");

		CompletableFuture<Void> voidFuture = twoFuture.thenAcceptBoth(oneFuture, (s, w) -> {
			System.out.println(s);
			System.out.println(w);
		});
	}

	/**
	 * 无入参,无返回值
	 */
	private static void runAfterBoth() {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> "one");
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> "two");

		twoFuture.runAfterBoth(oneFuture, () -> System.out.println("three"));
	}

	/****************** OR 两个任务有一个执行完执行 ******************/

	private static String sleepAndReturn(String str) {
		try {
			Thread.sleep(500L);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		System.out.println(str);
		return str;
	}

	private static String returnStr(String str) {
		System.out.println(str);
		return str;
	}

	/**
	 * 传参、有返回值
	 */
	private static void applyToEither() throws Exception {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> sleepAndReturn("one"));
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> returnStr("two"));

		CompletableFuture<String> threeFuture = twoFuture.applyToEither(oneFuture, (val) -> {
			System.out.println(val);
			return "three";
		});

		System.out.println(threeFuture.get());
	}

	/**
	 * 传参、无返回值
	 */
	private static void acceptEither() {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> sleepAndReturn("one"));
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> returnStr("two"));

		// void
		CompletableFuture<Void> threeFuture = twoFuture.acceptEither(oneFuture, System.out::println);
	}

	/**
	 * 无传参,无返回值
	 */
	private static void runAfterEither() {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> sleepAndReturn("one"));
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> returnStr("two"));

		// void
		CompletableFuture<Void> threeFuture = twoFuture.runAfterEither(oneFuture, () -> System.out.println("three"));
	}

	/****************** AllOf ******************/

	private static void allOf() throws Exception {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> sleepAndReturn("one"));
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> returnStr("two"));
		CompletableFuture<String> threeFuture = CompletableFuture.supplyAsync(() -> returnStr("three"));

		// void
		CompletableFuture<Void> allFuture = CompletableFuture.allOf(oneFuture, twoFuture, threeFuture);
		allFuture.get();

		/*
		 * Notice that the return type of the CompletableFuture.allOf() is a CompletableFuture<Void>.
		 * The limitation of this method is that it does not return the combined results of all Futures.
		 * Instead, we have to get results from Futures manually.
		 * Fortunately, CompletableFuture.join() method and Java 8 Streams API makes it simple:
		 */
		List<String> resultList = Stream.of(oneFuture, twoFuture, threeFuture).map(CompletableFuture::join).collect(Collectors.toList());
		System.out.println(JSONUtil.toJsonStr(resultList));
	}

	/****************** anyOf ******************/

	private static void anyOf() throws Exception {
		CompletableFuture<String> oneFuture = CompletableFuture.supplyAsync(() -> sleepAndReturn("one"));
		CompletableFuture<String> twoFuture = CompletableFuture.supplyAsync(() -> returnStr("two"));
		CompletableFuture<String> threeFuture = CompletableFuture.supplyAsync(() -> returnStr("three"));

		// object
		CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(oneFuture, twoFuture, threeFuture);
		System.out.println("result is " + anyFuture.get());
	}

	/****************** thenCompose ******************/

	private static void thenCompose() {

	}
}
posted @ 2022-12-03 23:28  Tailife  阅读(248)  评论(0编辑  收藏  举报