CompletableFuture功能测试

CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背。 为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。 CompletionStage是一个接口,从命名上看得知是一个完成的阶段,它里面的方法也标明是在某个运行阶段得到了结果之后要做的事情。

package java8test.Java8Future;

import java.util.concurrent.CompletableFuture;

/**
 * 描述:
 * Created 002267 by on 2017-10-18 21:00:54
 */
public class CompletableFutureTest {

	public static void main(String[] args) {

		CompletableFutureTest test = new CompletableFutureTest();
		//        test.thenApply();

		//future callback

		//        test.thenAccept();

		//        test.thenRun();

		test.thenCombine();
	}

	//它的入参是上一个阶段计算后的结果,返回值是经过转化后结果
	public void thenApply() {
		String result = CompletableFuture.supplyAsync(() -> "hello").thenApply(s -> s + " world").join();
		System.out.println(result);

	}


	//thenAccept是针对结果进行消耗,因为他的入参是Consumer,有入参无返回值。
	public void thenAccept() {
		CompletableFuture.supplyAsync(() -> "hello").thenAccept(s -> System.out.println(s + " world"));
	}

	//对上一步的计算结果不关心,执行下一个操作
	public void thenRun() {
		//        Future<String>
		CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(20 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "hello";
		}).thenRun(() -> System.out.println("hello world then run"));
		while (true) {
			try {
				System.out.println("<<<running>>>");
				Thread.sleep(10 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void aa(){
		asyncFile().whenComplete((val, throwable) ->{
			System.out.println("sdafsadfsdafsdafdsaf");
		});


		System.out.println("query user");

	}
	//  if (!file.isEmpty()) asyncFile(file).whenComplete((val, throwable) -> bannerInfoDto.setBannerUrl(val));a
	private CompletableFuture<String> asyncFile() {
		CompletableFuture<String> futurePrice = new CompletableFuture<>();
		new Thread(() -> {
			System.out.println("12312312");
		}).start();
		return futurePrice;
	}

	//结合两个CompletionStage的结果,进行转化后返回
	public void thenCombine() {
		String result = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "hello";
		}).thenCombine(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "world";
		}), (s1, s2) -> s1 + " " + s2).join();
		System.out.println(result);
	}

	//结合两个CompletionStage的结果,进行消耗
	public void thenAcceptBoth() {
		CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "hello";
		}).thenAcceptBoth(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "world";
		}), (s1, s2) -> System.out.println(s1 + " " + s2));
		while (true) {
		}
	}

	//在两个CompletionStage都运行完执行。

	public void runAfterBoth() {
		CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s1";
		}).runAfterBothAsync(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s2";
		}), () -> System.out.println("hello world"));
		while (true) {
		}
	}

	//两个CompletionStage,谁计算的快,我就用那个CompletionStage的结果进行下一步的转化操作。
	public void applyToEither() {
		String result = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s1";
		}).applyToEither(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "hello world";
		}), s -> s).join();
		System.out.println(result);
	}

	//两个CompletionStage,谁计算的快,我就用那个CompletionStage的结果进行下一步的消耗操作。
	public void acceptEither() {
		CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s1";
		}).acceptEither(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "hello world";
		}), System.out::println);
		while (true) {
		}
	}

	//两个CompletionStage,任何一个完成了都会执行下一步的操作(Runnable)
	public void runAfterEither() {
		CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s1";
		}).runAfterEither(CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "s2";
		}), () -> System.out.println("hello world"));
		while (true) {
		}
	}

	//当运行时出现了异常,可以通过exceptionally进行补偿。
	public void exceptionally() {
		String result = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (1 == 1) {
				throw new RuntimeException("测试一下异常情况");
			}
			return "s1";
		}).exceptionally(e -> {
			System.out.println(e.getMessage());
			return "hello world";
		}).join();
		System.out.println(result);
	}

	//当运行完成时,对结果的记录。这里的完成时有两种情况,一种是正常执行,返回值。另外一种是遇到异常抛出造成程序的中断。这里为什么要说成记录,因为这几个方法都会返回CompletableFuture,当Action执行完毕后它的结果返回原始的CompletableFuture的计算结果或者返回异常

	public void whenComplete() {
		String result = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (1 == 1) {
				throw new RuntimeException("测试一下异常情况");
			}
			return "s1";
		}).whenComplete((s, t) -> {
			System.out.println(s);
			System.out.println(t.getMessage());
		}).exceptionally(e -> {
			System.out.println(e.getMessage());
			return "hello world";
		}).join();
		System.out.println(result);
	}

	//行完成时,对结果的处理。这里的完成时有两种情况,一种是正常执行,返回值。另外一种是遇到异常抛出造成程序的中断。
	public void handle() {
		String result = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//出现异常
			if (1 == 1) {
				throw new RuntimeException("测试一下异常情况");
			}
			return "s1";
		}).handle((s, t) -> {
			if (t != null) {
				return "hello world";
			}
			return s;
		}).join();
		System.out.println(result);
	}


}