多线程之@Async异步注解

一、应用背景

        通常,在Java中的方法调用采用的是同步调用,比如如果A()方法中调用了B()方法,则在A()方法调用B()方法之后,需要等待B()方法执行并返回后,A()方法才可以继续往下执行。这样容易导致一个问题,就是如果B()方法中的代码执行时间过长,则可能会导致调用A()方法的请求响应迟缓或者超时。为了解决这个问题,则可以使用Spirng框架下的注解@Async,通过异步调用的方式处理。本文主要是通过示例演示@Async在方法中的异步调用。

二、异步调用概念

        方法A()调用方法B(),如果B()是一个异步方法,则A()方法在调用B()方法之后,不用等待B()方法执行反馈,则直接可以往下继续执行A()方法的其他代码。

三、异步调用注解@Async介绍

        在Spring中,使用@Async标注某方法,可以使该方法变成异步方法,这些方法在被调用的时候,将会在独立的线程中进行执行,调用者不需等待该方法执行完成。但Spring中使用@Async注解,需要使用@EnableAsync来开启异步调用。

四、演示示例

注释:本文的演示示例均基于springboot框架下进行编码。

1.Controller层:

@RestController
@EnableAsync

public class TreadController {
   
@Autowired
   
private TreadService service;
   
@RequestMapping("/ordManager")
   
public Integer getOrderId() throws InterruptedException {
        System.
out.println("controller开始层打印日志");
       
service.orderLog();
       
System.out.println("controller结束层打印日志");
        return
3;
   
}
}

2.Service层:

@Service
public class TreadService {
    @Async
    public void orderLog1() throws InterruptedException {
          try {
                Thread.sleep(3_000);
              } catch (Exception e) {
                }
                System.out.println("订单日志");
    }
}

代码运行结果:

如果不添加@EnableAsync注解,则会出现同步调用的现象。

代码运行结果:

五、手写@Async注解功能

原理:基于AOP+多线程的实现方式

  1. 编写自定义注解:@YdbAsync
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface YdbAsync {
    String value() default "";
}
  1. 编写AOP拦截功能:采用环绕通知方式
@Aspect
public class AsyncAop {
    @Pointcut("@annotation(com.ydb.annotation.YdbAsync)")
    private void annotation(){}
    @Around("annotation()")
    public void aroundAspect(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Aspect--环绕通知方法开始执行!!!");
        joinPoint.proceed();
        System.out.println("Aspect--环绕通知方法开结束执行!!");
    }
}
  1. 在目标方法中添加@YdbAsync,并增加线程运行
@YdbAsync
public void orderLog() throws InterruptedException {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(3_000);
            } catch (Exception e) {
            }
            System.out.println("订单日志");
        }
    });
    thread.start();
}
  1. 修改contoller层调用方法
@RestController
//@EnableAsync
public class TreadController {
    @Autowired
    private TreadService service;

    @RequestMapping("/ordManager")
    public Integer getOrderId() throws InterruptedException {
        System.out.println("controller开始层打印日志");
        service.orderLog();
        System.out.println("controller结束层打印日志");
        return 3;
    }
}

注释:手写异步调用注解不需要添加@EnableAsync注解

代码运行结果:

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值