SpringBoot之异步方法

本文详细介绍了SpringBoot中两种异步处理方式:Future和CompletableFuture。Future仅能表示异步计算结果,而CompletableFuture提供了丰富的回调方法和组合处理能力,如thenApply、exceptionally等。此外,文章还讲解了使用@Async注解实现异步方法的注意事项,包括异常处理和事务管理机制。
摘要由CSDN通过智能技术生成

1、Future

Future代表异步计算的结果。提供了检查计算是否完成、等待其完成以及检索计算结果的方法。只有在计算完成后,才能使用方法get检索结果,如有必要,将其阻塞,直到准备就绪。取消是通过取消方法执行的。还提供了其他方法来确定任务是否正常完成或被取消。

	//等待异步任务完成,然后检索其结果
    V get() throws InterruptedException, ExecutionException;
	//最多等待给定的时间以完成计算,然后检索其结果
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
	//如果此任务已完成,则返回true。完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法将返回true
	boolean isDone();


	private static final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
        int i = 0;

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "test-" + i++);
        }
    });
	
    public static void demo01() {
        log.info("创建异步任务");
        Future<String> submit = executor.submit(new Callable<String>() {
            @Override
            public String call() {
                String result = "fail";
                try {
                    log.info("开始执行异步任务");
                    // 执行任务耗时
                    Thread.sleep(10000);
                    result = "success";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return result;
            }
        });

        try {
            String result = submit.get();
            log.info("获取异步任务结果 " + result);
        } catch (InterruptedException e) {
            System.out.println("中断异常");
        } catch (ExecutionException e) {
            System.out.println("执行异常");
        }

        log.info("Future的get方法,会使当前线程阻塞");
    }

在这里插入图片描述

    public static void demo02() throws InterruptedException, ExecutionException {
        log.info("创建异步任务");
        Future<String> submit = executor.submit(new Callable<String>() {
            @Override
            public String call() {
                String result = "fail";
                try {
                    log.info("开始执行异步任务");
                    // 执行任务耗时
                    Thread.sleep(10000);
                    result = "success";
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return result;
            }
        });

        log.info("轮询调用isDone方法查询异步任务是否完成");
        while (true) {
            if (submit.isDone()) {
                String result = submit.get();
                log.info(result);
                break;
            } else {
                log.info("异步任务还未完成,先干点别的事");
                Thread.sleep(1000);
            }
        }

        log.info("Future的get方法,会使当前线程阻塞");
    }

在这里插入图片描述
使用Future,并不能实现真正的异步,要么需要阻塞的获取结果,要么不断的轮询

2、CompletableFuture

CompletableFuture实现了CompletionStage接口和Future接口,增加了异步回调、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。

	//创建带返回值的异步任务,要么使用的默认线程池ForkJoinPool.commonPool(),要么入参时给定		
	public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }
    
	//创建无返回值的异步任务,要么使用的默认线程池ForkJoinPool.commonPool(),要么入参时给定	
	public static CompletableFuture<Void> runAsync(Runnable runnable) {
        return asyncRunStage(asyncPool, runnable);
    }
    public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {
        return asyncRunStage(screenExecutor(executor), runnable);
    }

	//如果以任何方式完成,则返回true:正常、异常或通过取消
	public boolean isDone() {
        return result != null;
    }
	//等待此任务完成,然后返回其结果
    public T get() throws InterruptedException, ExecutionException {
        Object r;
        return reportGet((r = result) == null ? waitingGet(true) : r);
    }
	//最多等待给定的时间,以完成此任务,然后返回其结果
    public T get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        Object r;
        long nanos = unit.toNanos(timeout);
        return reportGet((r = result) == null ? timedGet(nanos) : r);
    }
    //如果任务完成则返回结果集,否则返回给定的valueIfAbsent
    public T getNow(T valueIfAbsent) {
        Object r;
        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
    }

thenApply / thenAccept / thenRun

在流式处理中,等待上层任务正常执行完成后,再执行回调方法;
thenApply:上层任务的结果值作为回调方法的入参值,该回调方法有返回值
thenAccept:上层任务的结果值作为回调方法的入参值,该回调方法没有返回值
thenRun:没有入参也没有返回值的回调方法

    public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {
        return uniApplyStage(null, fn);
    }
    public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn) {
        return uniApplyStage(asyncPool, fn);
    }
    public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor) {
        return uniApplyStage(screenExecutor(executor), fn);
    }

	public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
        return uniAcceptStage(null, action);
    }
    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
        return uniAcceptStage(asyncPool, action);
    }
    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor) {
        return uniAcceptStage(screenExecutor(executor), action);
    }


	public CompletableFuture<Void> thenRun(Runnable action) {
        return uniRunStage(null, action);
    }
    public CompletableFuture<Void> thenRunAsync(Runnable action) {
        return uniRunStage(asyncPool, action);
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值