Java异步编程

目录

需要异步编程的场景

Future

        Future接口有什么用?

FutureTask

        CompletableFuture 类有什么用?

 项目中Future的使用:

SpringBoot中异步编程的实现


需要异步编程的场景

线程从启动到执行完毕,一般会有一些耗时操作,并不能像一般的程序语句,就能立马结束。所以把这些耗时的操作交给子线程去处理,处理完了,返回结果就行;这样并不会阻塞主线程,使得主线程的任务更快的执行完成。异步调用是多线程领域的核心思想,并非 Java 语言独有。

Future

Future接口有什么用?

Future 接口是异步思想的典型运用,主要用在一些需要执行耗时任务的场景,避免程序一直原地等待耗时任务执行完成,执行效率太低。当执行某一耗时的任务时,可以将这个耗时任务交给一个子线程去异步执行,同时主线程做其他事情,不用等待耗时任务执行完成。等我其它事情干完后,再通过 Future 类获取到耗时任务的执行结果。这样程序的执行效率就明显提高了。

在 Java 中,Future 只是一个泛型接口,位于 java.util.concurrent 包下,其中定义了 5 个方法,主要包括下面这 4 个功能:

  • 取消任务;
  • 判断任务是否被取消;
  • 判断任务是否已经执行完成;
  • 获取任务执行结果。

FutureTask

可以通过 FutureTask 来理解 CallableFuture 之间的关系。

FutureTask 提供了 Future 接口的基本实现,常用来封装 CallableRunnable,具有取消任务、查看任务是否执行完成以及获取任务执行结果的方法。ExecutorService.submit() 方法返回的其实就是 Future 的实现类 FutureTask

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);

FutureTask 不光实现了 Future接口,还实现了Runnable 接口,因此可以作为任务直接被线程执行。

 

FutureTask 有两个构造函数,可传入 Callable 或者 Runnable 对象。实际上,传入 Runnable 对象也会在方法内部转换为Callable 对象。

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;
}
public FutureTask(Runnable runnable, V result) {
    // 通过适配器RunnableAdapter来将Runnable对象runnable转换成Callable对象
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;
}

FutureTask相当于对Callable 进行了封装,管理着任务执行的情况,存储了 Callablecall 方法的任务执行结果。

CompletableFuture 类有什么用?

Future 在实际使用过程中存在一些局限性比如不支持异步任务的编排组合、获取计算结果的 get() 方法为阻塞调用。

Java 8 引入CompletableFuture 类可以解决Future 的这些缺陷。CompletableFuture 除了提供了更为好用和强大的 Future 特性之外,还提供了函数式编程、异步任务编排组合(可以将多个异步任务串联起来,组成一个完整的链式调用)等能力。

下面来看 CompletableFuture 类的定义。

CompletableFuture 同时实现了 FutureCompletionStage 接口。

CompletionStage 接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。

CompletionStage 接口中的方法比较多,CompletableFuture 的函数式能力就是这个接口赋予的。从这个接口的方法参数可以发现其大量使用了 Java8 引入的函数式编程。

 项目中Future的使用:

在这里使用Future是为了让前端用户在调用Controller后可以同步的获得执行的结果;因为Callable是可以异步的返回计算结果。具体的代码实现是将要下单处理的流程使用 submit() 方法向线程池中添加任务;submit()有返回值,返回值对象类型是Future。submit执行的任务,可以通过Future对象的get方法接收抛出的异常,再抛出到异常处理层(本项目对所有异常集中统一处理)。

SpringBoot中异步编程的实现

在SpringBoot中将一个方法声明为异步方法非常简单,只需两个注解即可@EnableAsync和@Async。其中@EnableAsync用于开启SpringBoot支持异步的功能,用在SpringBoot的启动类上。@Async用于方法上,标记该方法为异步处理方法。

 前面说过:异步调用是多线程领域的核心思想,并非 Java 语言独有;Redis中持久化也用到了异步子线程的机制,等我后续补充!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值