【设计模式】JAVA Design Patterns——Async Method Invocation(异步方法调用模式)

简介: 【设计模式】JAVA Design Patterns——Async Method Invocation(异步方法调用模式)

🔍目的


异步方法调用是一个调用线程 在等待任务结果时不会阻塞的模式,模式为多个独立的任务提供并行的处理方式并且通过回调或等到它们全部完成来接受任务结果


🔍解释


真实世界例子

发射火箭是一项令人激动的事务。任务指挥官发出了发射命令,经过一段不确定的时间后,火箭要么成功发射,要么惨遭失败。


通俗描述

异步方法调用开始任务处理,并在任务完成之前立即返回。 任务处理的结果稍后返回给调用方。


维基百科

多线程计算机编程中,异步方法调用(AMI),也称为异步方法调用或异步模式,是一种设计模式,其中在等待被调用的代码完成时不会阻塞调用站点。 而是在执行结果到达时通知调用线程。轮询调用结果是不希望的选项


程序示例

假如我们正在发生太空火箭并部署月球漫游车。就可以演示异步调用模式。

模式的关键部分是AsyncResult(用于异步评估值的中间容器),AsyncCallback(可以在任务完成时被执行)和AsyncExecutor(用于管理异步任务的执行)。


创建异步评估的中间容器

public interface AsyncResult<T> {
  boolean isCompleted();
  T getValue() throws ExecutionException;
  void await() throws InterruptedException;
}


创建异步回调执行操作的类

public interface AsyncCallback<T> {
  void onComplete(T value, Optional<Exception> ex);
}


创建异步任务的执行器接口

public interface AsyncExecutor {
  <T> AsyncResult<T> startProcess(Callable<T> task);
  <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback);
  <T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
}


创建异步任务执行器的实现类

public class ThreadAsyncExecutor implements AsyncExecutor {
 
  @Override
  public <T> AsyncResult<T> startProcess(Callable<T> task) {
    return startProcess(task, null);
  }
 
  @Override
  public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
    var result = new CompletableResult<>(callback);
    new Thread(
            () -> {
              try {
                result.setValue(task.call());
              } catch (Exception ex) {
                result.setException(ex);
              }
            },
            "executor-" + idx.incrementAndGet())
        .start();
    return result;
  }
 
  @Override
  public <T> T endProcess(AsyncResult<T> asyncResult)
      throws ExecutionException, InterruptedException {
    if (!asyncResult.isCompleted()) {
      asyncResult.await();
    }
    return asyncResult.getValue();
  }
}


现在我们准备发射一个火箭

public static void main(String[] args) throws Exception {
  // 构造一个将执行异步任务的新执行程序
  var executor = new ThreadAsyncExecutor();
 
  // 以不同的处理时间开始一些异步任务,最后两个使用回调处理程序
  final var asyncResult1 = executor.startProcess(lazyval(10, 500));
  final var asyncResult2 = executor.startProcess(lazyval("test", 300));
  final var asyncResult3 = executor.startProcess(lazyval(50L, 700));
  final var asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Deploying lunar rover"));
  final var asyncResult5 =
      executor.startProcess(lazyval("callback", 600), callback("Deploying lunar rover"));
 
  // 在当前线程中模拟异步任务正在它们自己的线程中执行
  Thread.sleep(350); // 哦,兄弟,我们在这很辛苦
  log("Mission command is sipping coffee");
 
  // 等待任务完成
  final var result1 = executor.endProcess(asyncResult1);
  final var result2 = executor.endProcess(asyncResult2);
  final var result3 = executor.endProcess(asyncResult3);
  asyncResult4.await();
  asyncResult5.await();
 
  // log the results of the tasks, callbacks log immediately when complete
  // 记录任务结果的日志, 回调的日志会在回调完成时立刻记录
  log("Space rocket <" + result1 + "> launch complete");
  log("Space rocket <" + result2 + "> launch complete");
  log("Space rocket <" + result3 + "> launch complete");
}


在控制台中查看其执行内容

14:32:01.227 [executor-2] INFO com.iluwatar.async.method.invocation.App - Space rocket <test> launched successfully
14:32:01.269 [main] INFO com.iluwatar.async.method.invocation.App - Mission command is sipping coffee
14:32:01.318 [executor-4] INFO com.iluwatar.async.method.invocation.App - Space rocket <20> launched successfully
14:32:01.335 [executor-4] INFO com.iluwatar.async.method.invocation.App - Deploying lunar rover <20>
14:32:01.414 [executor-1] INFO com.iluwatar.async.method.invocation.App - Space rocket <10> launched successfully
14:32:01.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Space rocket <callback> launched successfully
14:32:01.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Deploying lunar rover <callback>
14:32:01.616 [executor-3] INFO com.iluwatar.async.method.invocation.App - Space rocket <50> launched successfully
14:32:01.617 [main] INFO com.iluwatar.async.method.invocation.App - Space rocket <10> launch complete
14:32:01.617 [main] INFO com.iluwatar.async.method.invocation.App - Space rocket <test> launch complete
14:32:01.618 [main] INFO com.iluwatar.async.method.invocation.App - Space rocket <50> launch complete


🔍类图


0a683a20c9d24577981c45977bc96051.png


🔍适用场景

在以下情况下使用异步方法调用模式

  • 您有多个可以并行运行的独立任务
  • 您需要提高一组顺序任务的性能
  • 您的处理能力或长时间运行的任务数量有限,并且调用方不应等待任务执行完毕

6e583dcee109441aab138b616db665dd.gif

相关文章
|
2月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
125 11
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
15天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
75 40
|
16天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
49 19
|
14天前
|
设计模式 Java
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
48 12
|
16天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
37 15
|
1月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
93 17
|
3月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
61 1
|
3月前
|
JavaScript Java 中间件
Java CompletableFuture 异步超时实现探索
本文探讨了在JDK 8中`CompletableFuture`缺乏超时中断任务能力的问题,提出了一种异步超时实现方案,通过自定义工具类模拟JDK 9中`orTimeout`方法的功能,解决了任务超时无法精确控制的问题,适用于多线程并行执行优化场景。