1、创建

/**
     * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier){..}
     * public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor){..}
     * public static CompletableFuture<Void> runAsync(Runnable runnable){..}
     * public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor){..}
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Test
    public void testCreateCompletableFuture() throws ExecutionException, InterruptedException {
        // 方式一:
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " ===> 执行任务,有返回值");
            return "qiu";
        });
        String result = future1.get();
        System.out.println("result = " + result);

        // 方式二:
        ExecutorService pool = Executors.newFixedThreadPool(2);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " ===> 执行任务,有返回值,自定义线程池");
            return "qiu";
        }, pool);
        result = future2.get();
        System.out.println("future2 = " + future2);

        // 方式三:
        CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " ===> 执行任务,无返回值");
        });

        // 方式四:
        CompletableFuture<Void> future4 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " ===> 执行任务,有返回值,自定义线程池");
        }, pool);
    }
  • supplyAsync :执行任务,支持返回值。
  • runAsync:执行任务,没有返回值。

2、结果获取

/**
     * //方式一
     * public T get()
     * //方式二
     * public T get(long timeout, TimeUnit unit)
     * //方式三
     * public T getNow(T valueIfAbsent)
     * //方式四
     * public T join()
     */
@SneakyThrows
@Test
public void testGet(){

	CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		System.out.println("执行了一个任务");
		return "qiu";
	});

	// getNow()
	String futureNow = future.getNow("立刻获取");
	System.out.println("futureNow = " + futureNow);

	// get(time):超时抛出异常
	// String r = future.get(10, TimeUnit.MICROSECONDS);
	// System.out.println("r = " + r);

	// get()
	String result = future.get();
	System.out.println("result = " + result);

	// join()
	CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println(1 / 0));
	future1.join();

}
  • get()和get(long timeout, TimeUnit unit) => 在Future中就已经提供了,后者提供超时处理,如果在指定时间内未获取结果将抛出超时异常
  • getNow => 立即获取结果不阻塞,结果计算已完成将返回结果或计算过程中的异常,如果未计算完成将返回设定的valueIfAbsent值
  • join => 方法里不会抛出异常

3、异步回调方法

thenRun()|thenRunAsync()
/**
		无参无返回值 : 做完第一个任务后,再做第二个任务,第二个任务也没有返回值
     * thenRun()
     * thenRunAsync()
     * @throws InterruptedException
     */
@Test
public void testUse() throws InterruptedException {
	ExecutorService pool = Executors.newFixedThreadPool(1);

	LocalDateTime startTime = LocalDateTime.now();

	CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		System.out.println(Thread.currentThread().getName() + "第一个任务");
	});
	// thenRun()
	CompletableFuture<Void> future1 = future.thenRun(() -> {
		try {
			Thread.sleep(400);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		System.out.println(Thread.currentThread().getName() + "第二个任务");
	});
	// thenRunAsync()
	future1.thenRunAsync(() -> {
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		System.out.println(Thread.currentThread().getName() + "第三个任务");
	},pool);
	Thread.sleep(1300);

	LocalDateTime endTime = LocalDateTime.now();
	Duration duration = Duration.between(startTime, endTime);
	System.out.println("共耗: " + duration.toHours() + " 小时, " + duration.toMinutes() + " 分钟, "
					   + duration.getSeconds() + " 秒, " + duration.toMillis() + " 毫秒");
}
如果你执行第一个任务的时候,传入了一个自定义线程池:
  • 调用thenRun方法执行第二个任务时,则第二个任务和第一个任务是共用同一个线程池。
  • 调用thenRunAsync执行第二个任务时,则第一个任务使用的是你自己传入的线程池,第二个任务使用的是ForkJoin线程池。
thenAccept()|thenAcceptAsync()
/**
     * 有参无返回值:第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,但是回调方法是没有返回值的。
     * thenAccept(params)
     * thenAcceptAsync(params)
     */
    @Test
    public void testAccept() throws ExecutionException, InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(2);

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "qiu");

        CompletableFuture<Void> accept = future.thenAccept((e) -> {
            System.out.println("上一个任务的返回值 = " + e);
        });

        // 无返回值 null
        System.out.println("accept.get() = " + accept.get());

        CompletableFuture<Void> accept2 = future.thenAcceptAsync((e) -> {
            System.out.println("上一个任务的返回值 = " + e);
        });
        System.out.println("accept2.get() = " + accept2.get());
    }
thenApply()|thenApplyAsync()
/**
     * 有参有返回值:表示第一个任务执行完成后,执行第二个回调方法任务,会将该任务的执行结果,作为入参,传递到回调方法中,并且回调方法是有返回值的
     * thenApply()
     * thenApplyAsync()
     */
    @Test
    public void testApply() throws ExecutionException, InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(2);

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "qiu");

        CompletableFuture<String> future1 = future.thenApply((e) -> e);
        System.out.println("上一个任务的返回值future = " + future1.get());

        CompletableFuture<String> future2 = future1.thenApplyAsync((e) -> e, pool);
        System.out.println("上一个任务的返回值future1 = " + future2.get());

    }

4、异常回调

whenComplete:当CompletableFuture的任务不论是正常完成还是出现异常它都会调用「whenComplete」这个回调函数。
  • 正常完成:whenComplete返回结果和上级任务一致,异常为null;
  • 出现异常:whenComplete返回结果为null,异常为上级任务的异常;
    即调用get()时,正常完成时就获取到结果,出现异常时就会抛出异常,需要你处理该异常
/**
     * whenComplete:
     */
    @Test
    public void testWhenComplete() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("出错了!!!");
            }
            System.out.println("正常结束");
            return 11;
        }).whenComplete((e, t) -> {
            if (e == null) {
                System.out.println("whenComplete e is null");
            } else {
                System.out.println("whenComplete e is " + e);
            }
            if (t == null) {
                System.out.println("whenComplete t is null");
            } else {
                System.out.println("whenComplete t is " + t.getMessage());
            }
        });
        System.out.println("结果 = " + future.get());
    }
whenComplete + exceptionally exceptionally会捕获任务执行中的异常,然后给一个默认的返回值
@Test
    public void testWhenComplete() throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            if (Math.random() < 0.5) {
                throw new RuntimeException("出错了!!!");
            }
            System.out.println("正常结束");
            return 11;
        }).whenComplete((e, t) -> {
            if (e == null) {
                System.out.println("whenComplete e is null");
            } else {
                System.out.println("whenComplete e is " + e);
            }
            if (t == null) {
                System.out.println("whenComplete t is null");
            } else {
                System.out.println("whenComplete t is " + t.getMessage());
            }
        }).exceptionally(t -> {
            System.out.println("出现异常了:" + t.getMessage());
            return 0;
        });
        System.out.println("结果 = " + future.get());
    }

结果:

whenComplete e is null
whenComplete t is java.lang.RuntimeException: 出错了!!!
出现异常了:java.lang.RuntimeException: 出错了!!!
结果 = 0

5、多任务组合之 AND

/**
     * 多任务组合之 AND
     * thenCombine / thenAcceptBoth / runAfterBoth都表示:「当任务一和任务二都完成再执行任务三」。
     * 区别在于:
     *   runAfterBoth: 不会把执行结果当做方法入参,且没有返回值
     *   thenAcceptBoth: 会将两个任务的执行结果作为方法入参,传递到指定方法中,且无返回值
     *   thenCombine: 会将两个任务的执行结果作为方法入参,传递到指定方法中,且有返回值
     */
    @Test
    public void testAnd() throws ExecutionException, InterruptedException {
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //开启异步任务1
        CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务1,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 1;
            System.out.println("异步任务1结束");
            return result;
        }, executorService);

        //开启异步任务2
        CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务2,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 1;
            System.out.println("异步任务2结束");
            return result;
        }, executorService);

        //任务组合
        CompletableFuture<Integer> task3 = task.thenCombineAsync(task2, (f1, f2) -> {
            System.out.println("执行任务3,当前线程是:" + Thread.currentThread().getId());
            System.out.println("任务1返回值:" + f1);
            System.out.println("任务2返回值:" + f2);
            return f1 + f2;
        }, executorService);

        Integer res = task3.get();
        System.out.println("最终结果:" + res);
    }

6、多任务组合之 OR

/**
     * 多任务组合之 OR
     * applyToEither / acceptEither / runAfterEither 都表示:「两个任务,只要有一个任务完成,就执行任务三」。
     * 区别在于:
     * runAfterEither:不会把执行结果当做方法入参,且没有返回值
     * acceptEither: 会将已经执行完成的任务,作为方法入参,传递到指定方法中,且无返回值
     * applyToEither:会将已经执行完成的任务,作为方法入参,传递到指定方法中,且有返回值
     */
    @Test
    public void testOR() {
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 开启异步任务1
        CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务1,当前线程是:" + Thread.currentThread().getId());

            int result = 1 + 1;
            System.out.println("异步任务1结束");
            return result;
        }, executorService);

        // 开启异步任务2
        CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务2,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 2;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步任务2结束");
            return result;
        }, executorService);

        // 任务组合
        task.acceptEitherAsync(task2, (res) -> {
            System.out.println("执行任务3,当前线程是:" + Thread.currentThread().getId());
            System.out.println("上一个任务的结果为:" + res);
        }, executorService);
    }

7、多任务组合

allOf:等待所有任务完成
@Test
    public void testallOf() throws ExecutionException, InterruptedException {
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //开启异步任务1
        CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务1,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 1;
            System.out.println("异步任务1结束");
            return result;
        }, executorService);

        //开启异步任务2
        CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务2,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 2;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步任务2结束");
            return result;
        }, executorService);

        //开启异步任务3
        CompletableFuture<Integer> task3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务3,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 3;
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步任务3结束");
            return result;
        }, executorService);

        //任务组合,这里可以理解为,当我们需要去其他系统调用数据时,组合所有任务
        CompletableFuture<Void> allOf = CompletableFuture.allOf(task, task2, task3);

        //等待所有任务完成
        allOf.get();

        //获取任务的返回结果
        System.out.println("task结果为:" + task.get());
        System.out.println("task2结果为:" + task2.get());
        System.out.println("task3结果为:" + task3.get());
    }
anyOf() : 只要有一个任务完成
@Test
    public void testAnyOf() throws ExecutionException, InterruptedException {
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //开启异步任务1
        CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务1,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 1;
            System.out.println("异步任务1结束");
            return result;
        }, executorService);

        //开启异步任务2
        CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务2,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 2;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步任务2结束");
            return result;
        }, executorService);

        //开启异步任务3
        CompletableFuture<Integer> task3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步任务3,当前线程是:" + Thread.currentThread().getId());
            int result = 1 + 3;
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步任务3结束");
            return result;
        }, executorService);

        //任务组合,这里可以理解为,当我们需要去其他系统调用数据时,组合所有任务
        CompletableFuture<Object> future = CompletableFuture.anyOf(task, task2, task3);

        //某一人任务完成
        Object res = future.get();
        System.out.println("res = " + res);

        //获取任务的返回结果
        System.out.println("task结果为:" + task.get());
        System.out.println("task2结果为:" + task2.get());
        System.out.println("task3结果为:" + task3.get());
    }

原文地址:http://www.cnblogs.com/qbbit/p/16912929.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性