Spring中@Async

Spring 异步@Async注解用法 Spring @Async注解用法总结 Spring @Async基本用法示例 一、概述在日常开发的工作中,经常会使用异步进行开发。Spring 提供一个简单的注解 @Async ,即可实现异步的开发,无需创建线程池,简单明了。本文将整理@Async的常见用法,包括:基础入门,获取返回值,配置线程池,异常处理等。@Async 注解实现原理,请自行查看源码,从:org.springframework.aop.interceptor.开始...1、本文相对详细的记录@Async 注解的常见用法,可以满足日常大部分的开发需求。2、注意一点: 在同一个类中,是可以存在异步方法。 阅读详情

一、简述

在 Java 应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务。其实,在 Spring3.x 之后,就已经内置了 @Async 来完美解决这个问题。

二、何为异步调用

在解释异步调用之前,先来看同步调用的定义:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕,而是继续执行下面的流程。

例如,在某个调用中,需要顺序调用ABC三个过程方法;如它们都是同步调用,则需要将它们都顺序执行完毕之后,才能算是过程执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。

三、常规的异步调用处理方式

在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。

四、@Async介绍

在Spring中,基于@Async标注的方法,称之为异步方法。方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。有两种方式在Spring中启用@Async:

1️⃣基于Java配置的启用方式:

@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }

2️⃣基于XML配置文件的启用方式,配置如下:

<task:executor id="myexecutor" pool-size="5"  />
<task:annotation-driven executor="myexecutor"/>

五、基于@Async无返回值调用

@Async  //标注使用
public void asyncMethodWithVoidReturnType() {
    System.out.println("Execute method asynchronously. "
      + Thread.currentThread().getName());
}

使用的方式非常简单,一个标注即可解决所有的问题。

六、基于@Async返回值的调用

@Async
public Future<String> asyncMethodWithReturnType() {
    System.out.println("Execute method asynchronously - "
      + Thread.currentThread().getName());
    try {
        Thread.sleep(5000);
        return new AsyncResult<String>("hello world !!!!");
    } catch (InterruptedException e) {
        //
    }
    return null;
}

以上示例可以发现,返回的数据类型为Future类型,其为一个接口。具体的结果类型为AsyncResult,这个是需要注意的地方。

调用返回结果的异步方法示例:

public void testAsyncAnnotationForMethodsWithReturnType()
   throws InterruptedException, ExecutionException {
    System.out.println("Invoking an asynchronous method. "
      + Thread.currentThread().getName());
    Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();

    while (true) {  ///这里使用了循环判断,等待获取结果信息
        if (future.isDone()) {  //判断是否执行完毕
            System.out.println("Result from asynchronous process - " + future.get());
            break;
        }
        System.out.println("Continue doing something else. ");
        Thread.sleep(1000);
    }
}

分析: 这些获取异步方法的结果信息,是通过不停的检查Future的状态来获取当前的异步方法是否执行完毕来实现的。

七、基于@Async调用中的异常处理机制

在异步方法中,如果出现异常,对于调用者caller而言,是无法感知的。如果确实需要进行异常处理,则按照如下方法来进行处理:

1️⃣自定义实现AsyncTaskExecutor的任务执行器
在这里定义处理具体异常的逻辑和方式。
2️⃣配置由自定义的TaskExecutor替代内置的任务执行器

示例步骤1,自定义的TaskExecutor

public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor {
    private AsyncTaskExecutor executor;
    public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) {
        this.executor = executor;
     }
      ////用独立的线程来包装,@Async其本质就是如此
    public void execute(Runnable task) {
      executor.execute(createWrappedRunnable(task));
    }
    public void execute(Runnable task, long startTimeout) {
        /用独立的线程来包装,@Async其本质就是如此
       executor.execute(createWrappedRunnable(task), startTimeout);
    }
    public Future submit(Runnable task) { return executor.submit(createWrappedRunnable(task));
       //用独立的线程来包装,@Async其本质就是如此。
    }
    public Future submit(final Callable task) {
      //用独立的线程来包装,@Async其本质就是如此。
       return executor.submit(createCallable(task));
    }

    private Callable createCallable(final Callable task) {
        return new Callable() {
            public T call() throws Exception {
                 try {
                     return task.call();
                 } catch (Exception ex) {
                     handle(ex);
                     throw ex;
                   }
                 }
        };
    }

    private Runnable createWrappedRunnable(final Runnable task) {
         return new Runnable() {
             public void run() {
                 try {
                     task.run();
                  } catch (Exception ex) {
                     handle(ex);
                   }
            }
        };
    }
    private void handle(Exception ex) {
      //具体的异常逻辑处理的地方
      System.err.println("Error during @Async execution: " + ex);
    }
}

分析: 可以发现其是实现了AsyncTaskExecutor,用独立的线程来执行具体的每个方法操作。在createCallable和createWrapperRunnable中,定义了异常的处理方式和机制。

handle()就是未来我们需要关注的异常处理的地方。

配置文件中的内容:

<task:annotation-driven executor="exceptionHandlingTaskExecutor" scheduler="defaultTaskScheduler" />
<bean id="exceptionHandlingTaskExecutor" class="nl.jborsje.blog.examples.ExceptionHandlingAsyncTaskExecutor">
    <constructor-arg ref="defaultTaskExecutor" />
</bean>
<task:executor id="defaultTaskExecutor" pool-size="5" />
<task:scheduler id="defaultTaskScheduler" pool-size="1" />

分析: 这里的配置使用自定义的taskExecutor来替代缺省的TaskExecutor。

八、@Async调用中的事务处理机制

在@Async标注的方法,同时也适用了@Transactional进行了标注;在其调用数据库操作之时,将无法产生事务管理的控制,原因就在于其是基于异步处理的操作。

那该如何给这些操作添加事务管理呢?可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional。

例如:
方法A,使用了@Async/@Transactional来标注,但是无法产生事务控制的目的。
方法B,使用了@Async来标注,B中调用了C、D。C/D分别使用@Transactional做了标注,则可实现事务控制的目的。

Spring的异步详解(@Async) 编写配置类@Data//核心线程//最大线程//队列容量//保持时间//名称前缀使用自定义线程池@Component@Async("MyExecutor") //使用自定义的线程池(执行器)//...具体业务逻辑。 阅读详情

相关推荐

基于vue2的echarts3D地球

采用vue2+js实现了echarts3D地球的放大、缩小和旋转

qq_44699269的博客 1132

Spring异步方法注解 @Async

@Async0. 介绍在Spring 3.x之后,通过内置@Async标明异步方法,可以简化异步开发流程。@Async既可提供无返回值的调用,也可提供有返回值的调用,下文将分别介绍两种使用方式。1. 代码Demo1.1 线程池配置Spring线程池配置有两种基本配置方式,此处实用其中一种<task:executor id="myexecutor" pool-size="5" /> <task:

亘易的专栏 4101

薛定谔虚拟筛选实战:如何用PDB文件快速构建受体格点(避坑指南)

本文提供了薛定谔虚拟筛选实战指南,聚焦于如何从PDB文件快速、精准地构建受体格点。文章详细解析了可变残基的理性处理策略、基于配体尺寸的盒子量化设置方法,并分享了高级约束与排除体积的实战技巧,旨在帮助用户避开常见陷阱,提升虚拟筛选的成功率与效率。

weixin_28419039的博客 254

Spring之异步任务@Async详解分析

在业务场景中,有时需要使用自己定义的执行器来跑异步的业务逻辑,那该怎么办呢?答案是,自定义线程池。在方法上的@Async@Async("MyExecutor") //使用自定义的线程池(执行器) public void asyncCpsItemImportTask(Long platformId , String jsonList) {//...具体业务逻辑 } }

上善若泪 1万+

使用Linux安装yum报错 E: Unable to correct problems, you have held broken packages.

使用Linux安装yum报错 E: Unable to correct problems, you have held broken packages.

weixin_43205954的博客 2462

FAST-LIO2实战:如何在无人机上部署并实现厘米级定位(附ROS配置全流程)

本文详细介绍了如何在无人机上部署FAST-LIO2激光雷达惯性里程计系统,以实现厘米级精确定位。内容涵盖从硬件选型(如激光雷达与机载计算机)、软件环境配置(ROS Noetic)、传感器标定,到FAST-LIO2参数调优、与PX4飞控集成以及实际飞行测试的全流程。重点解决了实时定位中的外参标定、数据同步等关键问题,为无人机在无GPS或复杂光照环境下提供稳定可靠的定位解决方案。

weixin_29062865的博客 251

Spring 3.x(特别是 3.2+)中处理@Async异常的正确解决方案

在 Spring 3.1 中引入了接口,我们可以通过实现它来自定义异常处理,但这需要更多的手动配置。// 设置自定义的异常处理执行器 return new ExceptionHandlingAsyncTaskExecutor(executor);

lanwp5302的博客 506

手把手教你用Trae配置Python开发环境(含Claude 3.5代码生成实战)

本文详细介绍了如何使用字节跳动推出的Trae智能开发环境配置Python开发环境,并实战演示了Claude 3.5代码生成功能。从环境准备到项目初始化,再到AI辅助编码和调试优化,全面展示了Trae在提升开发效率方面的强大能力,特别适合Python开发者快速搭建项目和解决复杂问题。

weixin_28309571的博客 977

Spring中@Async注解实现异步

简单介绍 Spring为任务调度与异步方法执行提供了注解支持。通过在方法上设置@Async注解,可使得方法被异步调用。也就是说调用者会在调用时立即返回,而被调用方法的实际执行是交给Spring的TaskExecutor来完成。 @Async注解的开启 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;task:annotation-driven executor=&amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;an

zeng_ll的博客 2175

CloudCompare 二次开发(17)——点云添加均匀分布的随机噪声

使用CloudCompare编程实现点云添加随机噪声。

点云侠的博客 840

Qt图形几何之QRect详解:从基础操作到高级功能全解析

本文全面介绍了Qt框架中的QRect类,详细解析了其核心功能和使用方法。主要内容包括:1)QRect的基本概念与多种构造函数;2)矩形属性获取和状态判断方法;3)几何操作函数(移动、调整大小等);4)几何关系判断(包含、相交等);5)坐标变换和边距处理;6)实用功能与QRectF转换;7)综合应用示例(图形界面、碰撞检测、布局管理);8)性能优化建议和常见陷阱。通过丰富的代码示例,展示了QRect在Qt图形编程中的实际应用,帮助开发者掌握矩形处理的各项操作技巧,提升图形界面开发效率。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 119

阅读笔记-Spring异步处理@Async的使用以及原理

@Async的原理

ZULJ131的博客 1160

高级图像增强——模拟雨天,雾,雪,阳光,阴影,运动模糊,畸变等14种效果,同步扩充标签文件

本文提供了一些高级的,特殊的图像增强方法,具体包括、光。

Limiiiing的博客 1308

Spring @Async

Spring @Async注解学习使用

weixin_45339291的博客 996

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Spring 框架——@Async 注解

同步调用特点:调用方在发起方法调用后,必须等待被调用的方法完成并返回结果之后,才能继续执行后续的操作(即会阻塞)。在同步调用中,调用方和被调用方的执行顺序是严格按照调用顺序进行的。适用场景:依赖顺序:当某个操作必须在另一个操作完成后才能进行时。简单任务:当任务执行时间短且没有并发问题时。确保执行顺序:需要确保多个步骤按顺序完成,比如数据库事务处理。异步调用特点:调用方发起方法调用后,不必等待被调用的方法完成,而是可以继续执行后续的操作。

2509_93956183的博客 1051

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Spring注解之@Async

在Spring框架中,@Async注解依赖于Spring的AOP机制,而AOP是通过动态代理来实现的。当你手动使用new来实例化类时,Spring并不能管理这个实例,因此Spring的AOP机制也无法为其创建代理对象,导致像@Async这样的注解失效。

qq_48990935的博客 1436

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Spring @Async 使用

前言: 任何与业务逻辑没有直接关联的逻辑(横切关注点)或在调用者上下文中不需要响应以确定下一个流或任何业务的逻辑是Asyncronization的理想候选者。在Spring中使用@Async注释使用异步,如果你在方法上使用随机的@Async注释并且认为你的方法将在一个单独的线程中以异步方式调用这是错的。 要知道@Async如何工作的和它的特性,不然你就无法理解异步行为。 @Asy...

湖人•总冠军 9606

【@Async】一文带你深入学习Spring注解之@Async使用

Spring Boot的@Async注解提供了简单且强大的方式来实现异步处理。通过启用异步支持、定义异步方法并自定义TaskExecutor,可以高效地处理各种异步任务。掌握@Async注解的使用和原理,有助于提升应用程序的性能和响应速度。但是其局限性也是非常明显的,因此,要想用好该@Async注解,还是需要在此基础上加以扩展。我是Wasteland,下期文章再见!

weixin_51360020的博客 6931

@async 没有异步_Spring 异步执行之@Async揭秘

背景在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后,就已经内置了@Async来完美解决这个问题,本文将完成介绍@Async的用法。1. 何为异步调用?在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺序执行,当各个过程都...

weixin_35991223的博客 861

Spring中@Async用法总结

引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后,就已经内置了@Async来完美解决这个问题,本文将完成介绍@Async的用法。 1.  何为异步调用?     在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺

答案是肯定的 6289
上一篇: 线程通信的几种方式
下一篇: Java多线程优化
JFS_Study
博客等级 码龄6年 363粉丝 359原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JFS_Study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值