Java实现异步的4种方式

文章目录

  • 异步
    • 1、Future与Callable
    • 2. CompletableFuture
    • 3. Spring框架的异步支持
        • 3.1 启动类开启对Async的支持 @EnableAsync
        • 3.2 配置自定义线程池
        • 3.3 异步业务
        • 3.4 调用异步业务方法
    • 4. 使用消息队列
        • 4.1 安装RabbitMq
        • 4.2 使用
        • 4.3 MQ消息丢失以及重复消费问题
    • 5、总结

异步

异步(Asynchronous)是指在进行多任务处理时,各个任务的执行不依赖于其他任务的完成,无需等待一个操作完成后再开始下一个操作。与之相对的是同步(Synchronous),同步操作需要按顺序执行,每个步骤必须等待前一个步骤完成才能开始。

异步处理的优点包括但不限于:

  1. 提高效率:允许程序在等待某个慢操作(如I/O操作)完成的同时,继续执行其他任务,提高了系统的整体响应速度和吞吐量。
  2. 增强用户体验:在用户界面(UI)编程中,异步处理能防止界面冻结,保持应用的响应性。
  3. 解耦:通过事件驱动或消息队列的方式,异步处理有助于解耦系统组件,使它们可以独立地开发、部署和扩展。
  4. 可扩展性:对于大规模分布式系统,异步通信机制能够更容易地水平扩展,以应对高并发场景。

实现异步编程的技术和框架有很多,根据不同的应用场景和技术栈选择合适的方法,例如:

  • 回调函数:是最基础的异步处理方式,通过传入一个函数作为参数,在异步操作完成时调用该函数。
  • Promise/Promise链(JavaScript中)或Future(Java中):提供了更加优雅的异步编程模型,可以链式调用来组织异步操作。
  • async/await(现代编程语言中广泛支持):进一步简化异步代码,使得异步代码看起来更像是同步代码,提高可读性和可维护性。
  • 消息队列和事件总线:用于解耦系统组件,通过发布-订阅模式或命令模式处理异步消息。
  • 线程池和并发库:如Java的Executor框架,用于管理线程资源,执行异步任务。

选择合适的异步处理策略,可以显著提升软件系统的性能和用户体验。

在这里插入图片描述

1、Future与Callable

Java并发包中的FutureCallable接口提供了基本的异步编程模型。你可以通过ExecutorService提交一个实现了Callable的任务,它会返回一个Future对象。你可以在这个Future对象上调用get()方法来获取结果,这个方法会阻塞直到结果可用。

Java

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AsyncExample {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        
        Callable<String> task = () -> {
            Thread.sleep(2000); // 模拟耗时操作
            return "Task completed!";
        };
        
        Future<String> future = executor.submit(task);
        
        System.out.println("Doing something else...");
        
        // 非阻塞方式检查结果是否准备好了
        while (!future.isDone()) {
            Thread.sleep(100);
            System.out.println("Waiting for result...");
       }
        
        System.out.println(future.get()); // 获取并打印结果
       
        executor.shutdown();
    }
}

2. CompletableFuture

从Java 8开始,CompletableFuture为异步编程提供了一个更强大、灵活的API,支持链式调用、组合多个异步操作以及更复杂的异步控制流。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class AsyncExampleWithCompletableFuture {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> {
            sleep(2000); // 模拟耗时操作
           return "Hello";
        }).thenAccept(result -> System.out.println("Result: " + result));
        
        System.out.println("Doing something else concurrently...");
    }
    
    private static void sleep(int millis) {
        try {
           Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3. Spring框架的异步支持

如果你的项目使用了Spring框架,Spring提供了对异步方法的直接支持。你只需要用@Async注解标记希望异步执行的方法,并配置一个异步任务执行器(TaskExecutor)。

3.1 启动类开启对Async的支持 @EnableAsync
@SpringBootApplication
@EnableScheduling
@EnableAsync
@MapperScan("com.example.demo.dao")
public class SpringBoot3DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot3DemoApplication.class, args);
    }

}
3.2 配置自定义线程池
@Configuration
public class AsyncConfig {
    @Bean(name = "myAsyncThreadPool")
    public ThreadPoolTaskExecutor asyncThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); // 核心线程数
        executor.setMaxPoolSize(10); // 最大线程数
        executor.setQueueCapacity(200); // 队列大小
        executor.setThreadNamePrefix("Async-"); // 线程前缀名
        executor.initialize();
        return executor;
    }
}
3.3 异步业务
@Service
@Slf4j
public class AsyncService {
    @Async("myAsyncThreadPool")
    public void asyncMethod1() {
        log.info("asyncMethod1 start");
        try {
            //发送短信...
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("发送短信 成功");
    }
    @Async("myAsyncThreadPool")
    public void asyncMethod2() {
        log.info("asyncMethod2 start");
        try {
            //通知物流...
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("通知物流 成功");
    }
}
3.4 调用异步业务方法
@Slf4j
@RestController
@Tag(name = "测试控制器")
@RequestMapping("test")
public class TestController {

    @Resource
    private AsyncService asyncService;

    @Operation(summary = "下单")
    @PostMapping("placeAnOrder")
    public CommonResult<String> placeAnOrder() {
        // 主线程-》参数校验、扣减库存、优惠券状态更新、创建订单
        // 异步线程1-》发送短信
        asyncService.asyncMethod1();
        // 异步线程2-》通知物流
        asyncService.asyncMethod2();
        return CommonResult.SUCCESS("下单成功");
    }
}

4. 使用消息队列

对于更复杂的异步处理需求,特别是需要跨服务通信或解耦不同服务组件的情况,可以考虑引入消息队列(如RabbitMQ、Kafka等)。通过发布-订阅模式或点对点模式,将任务放入队列,由专门的消费者异步处理。

4.1 安装RabbitMq

Linux下载安装 RabbitMQ

win10下安装 RabbitMQ

4.2 使用

RabbitMQ快速上手以及RabbitMQ交换机的四种模式

4.3 MQ消息丢失以及重复消费问题

RabbitMQ解决消息丢失以及重复消费问题

5、总结

总结每种方案的选择取决于具体的应用场景、复杂度和性能要求。简单的异步任务可能仅需使用FutureCallable,而复杂的异步流程控制和跨服务通信则可能更适合采用CompletableFuture或消息队列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/662525.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在线思维导图编辑!3个AI思维导图生成软件推荐!

思维导图&#xff0c;一种以创新为驱动的视觉化思考工具&#xff0c;已经渗透到我们日常生活和工作的各个角落。当我们需要整理思绪、规划项目或者梳理信息时&#xff0c;思维导图总能提供极大的帮助。 近些年随着云服务等基础设施的完善&#xff0c;我们可以看到越来越多提供…

Vue3实战笔记(34)—完美的菜单组件封装

文章目录 前言多层菜单封装总结 前言 之前简单的封装了一下菜单组件&#xff0c;数据都是写死的&#xff0c;多层嵌套没有支持&#xff0c;学完了组件传值&#xff0c;计算属性就可以继续完善了。 多层菜单封装 先看下数据结构&#xff1a; {"id":"1",&q…

手推车式电缆故障定位系统

武汉凯迪正大一体化电缆故障高压发生器用于测试各种型号的380V,600V,10kV,35kV,110kV,220kV,380kV电压等级的铜铝芯电力电缆、同轴通信电缆和市话电缆的各类故障&#xff0c;如电缆全长、开路、短路、断线、低阻故障、高阻故障、高阻泄露、高低阻抗接地、接地故障、铠装接地故障…

研发设计管理、研发设计管理系统有哪些

研发设计管理系统种类繁多&#xff0c;每种系统都有其特定的功能和用途。以下是一些常见的研发设计管理系统及其主要功能&#xff1a; PLM&#xff08;产品生命周期管理&#xff09;研发管理系统&#xff1a; 功能&#xff1a;管理产品从概念、设计、开发、制造、销售到维护的…

读《Diffusion Models: A Comprehensive Survey of Methods and Applications》综述

读《Diffusion Models: A Comprehensive Survey of Methods and Applications》综述 关于此文&#xff0c;我的一个见解想法&#xff0c;重点关注他怎么描述 「Diffusion Model」的引用的&#xff0c;以及未来方向就好了。当然从这篇文章可以知道 「Diffusion Model」的一个基石…

芝加哥大学最新研究:GPT-4与财务预测,重塑财务分析的未来

最近&#xff0c;芝加哥大学的研究团队发表了一篇突破性的研究&#xff0c;展示了大型语言模型&#xff08;LLM&#xff09;&#xff0c;特别是 OpenAI 开发的 GPT-4&#xff0c;如何在财务报表分析领域取得了与专业分析师相匹配甚至超越的表现。这项研究不仅凸显了人工智能在高…

Firefox国际版

Firefox国际版官方网址&#xff1a; Download the Firefox Browser in English (US) and more than 90 other languagesEveryone deserves access to the internet — your language should never be a barrier. That’s why — with the help of dedicated volunteers around…

Docker-----emqx部署

emqx通过Docker容器化部署流程 1.创建持久化挂载目录 mkdir -p /home/emqx/etc ------挂载emqx的配置文件目录 mkdir -p /home/emqx/data ------挂载emqx的存储目录 mkdir -p /home/emqx/log ------挂载emqx的日志目录 [root home]# mkdir -p /home/emqx/etc [root home]# mkd…

C++ vector 模拟实现

vector的底层也是一个动态数组&#xff0c;他与 string 的区别就是&#xff0c;string 是专门用来存储字符类数据的&#xff0c;为了兼容C语言&#xff0c;使用C语言的接口&#xff0c;在string的动态数组内都会都开一块空间用来存 \0 &#xff0c;而vector则不会。 首先我们要…

文本生成流程图 泰酷啦 Excalidraw Mermaid Obsidian

前言 介绍一个很酷的工具&#xff0c;Mermaid to Excalidraw 。作用是用代码生成流程图。 Mermaid 是一款强大的、轻量级的文本到图表的转换工具&#xff0c;它允许用户使用简单的Markdown风格的语法编写文本描述&#xff0c;然后通过JavaScript引擎将其转换成美观的图表。Mer…

YOLOv5改进 | 注意力机制 | 添加双重注意力机制 DoubleAttention【附代码/涨点能手】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 在图像识别中&#xff0c;学习捕捉长距离关系是基础。现有的CNN模型通常通过增加深度来建立这种关系&#xff0c;但这种形式效率极低。因此&…

在VSCode 中增加文件与文件夹的可辨识度

今天重新打开VSCode&#xff0c;打算新建一个项目做测试&#xff0c;看到VSCode中的文件与文件夹很不容易辨认&#xff0c;有时候容易导致一些误操作&#xff0c;需要做一些配置来改变。 效果图&#xff1a; 只需要做简单的2步就可以了。 1、安装插件 ⑴ 打开VSCode的扩展搜索并…

服务器的远程桌面无法连接,服务器远程桌面无法连接问题处理教程

服务器的远程桌面无法连接&#xff0c;服务器远程桌面无法连接问题处理教程。 一、问题概述 服务器远程桌面无法连接是日常运维中常见的问题之一。它可能由多种原因造成&#xff0c;如网络问题、服务器配置错误、远程桌面服务未启动等。本教程将指导您逐步排查并解决这些问题。…

yolov10 瑞芯微RKNN、地平线Horizon芯片部署、TensorRT部署,部署工程难度小、模型推理速度快

特别说明&#xff1a;参考官方开源的yolov10代码、瑞芯微官方文档、地平线的官方文档&#xff0c;如有侵权告知删&#xff0c;谢谢。 模型和完整仿真测试代码&#xff0c;放在github上参考链接 模型和代码。 yolov8、v9还没玩热乎&#xff0c;这不yolov10又来了&#xff0c;那么…

定点化和模型量化(三)

量化解决的是训练使用的浮点和运行使用的硬件只支持定点的矛盾。这里介绍一些实际量化中使用到的工具。 SNPE简介 The Snapdragon Neural Processing Engine (SNPE)是高通骁龙为了加速网络模型设计的框架。但它不只支持高通&#xff0c;SNPE还支持多种硬件平台&#xff0c;AR…

软件即服务-SaaS

目录 1. SaaS成熟度模型 2. SaaS应用平台 3. SaaS应用实现层次 4. 多租户技术 5. 可配置性 5.1 业务构件 5.2 数据可配置 5.2.1 定制字段 5.2.2 预分配字段 5.2.3 名称值对 5.3 功能可配置 5.3.1 业务构件设计 5.3.2 功能包设计 5.3.3 销售包设计…

Postman快捷功能-批量断言与快速查询替换

大家好&#xff0c;在我们日常的接口测试工作中&#xff0c;经常需要对接口返回的数据进行断言&#xff0c;以确保接口的正确性。当接口数量较多时&#xff0c;逐个编写断言语句会变得非常繁琐。此外&#xff0c;在接口测试过程中&#xff0c;我们还可能需要频繁地查找和替换某…

遇到软件测试职业瓶颈,如何突破

作为职场人&#xff0c;遇到发展瓶颈是在所难免的&#xff0c;无论是晋升受限、技能升级缓慢&#xff0c;还是工作激情的丢失&#xff0c;这些挑战都可能让人感到挫败。但是&#xff0c;积极应对&#xff0c;你就可能找到那扇通向新机遇的窗。 1. 自我评估 识别问题 是缺乏技能…

内存卡频频提示格式化?数据恢复全攻略

内存卡提示需要格式化 在数字时代&#xff0c;内存卡作为我们存储数据的常用设备&#xff0c;广泛应用于手机、相机、无人机等多种设备中。然而&#xff0c;不少用户在使用过程中会突然遭遇一个令人头疼的问题——内存卡提示需要格式化。这一提示往往伴随着数据的丢失风险&…

MobaXterm下载虚拟机SSH链接超时解决(保姆级踩坑)

文章目录 为啥要用MobaXtermMobaXterm下载打开虚拟机ssh链接ssh连接失败排查linux配置windows配置 到这了&#xff0c;什么都干了&#xff0c;怎么还不成功&#xff1f; 更多相关内容可查看 在一个阳光明媚的下午&#xff0c;开启了无限踩坑的旅程 为啥要用MobaXterm 作为小编…