Spring中的@Async注解 异步任务处理

使用需求

在开发中,我们往往有一些特殊的需求,例如log、邮件、用户op的记录、来访者信息的记录等等。如果将这些操作放在他自己的线程中执行,会不会对程序造成阻塞呢?当高并发的情况下,任务的实时性还存在么?

@Async

Spring中为我们提供了@Async注解,异步的去处理。那如何去理解呢?
如果一个方法上加了@Async注解,表明这个方法将由一个新线程区执行而调用他的方法还在原线程执行,就好比去单独启用了一个服务去做记录,而不是在原方法中执行记录

注:加在类上代表该类中所有方法都为异步,若方法也加了该注解,以方法的配置为准

配置

<!--&lt;!&ndash;开启注解调度支持 @Async @Scheduled&ndash;&gt;-->
    <task:annotation-driven proxy-target-class="true"/>

其中的proxy-target-class=”true”表示要使用一个指定的类,让Spring来生成它的bean,并使用他的某个方法,“true”或“false”决定是基于接口还是基于类的代理被创建,当true时基于类,默认为false

还包含其他属性

//指定一个省缺的执行器
executor="asyncExecutor"  

task:executor的配置参数

//用@Async("loggerExecutor")来指定
id="loggerExecutor"

//池大小
pool-size = "20-1000"

//队列容量 决定了当任务达到多少时,pool创建新的线程去处理任务
queue-capacity="5"

//最大线程数
max size = "10"
//最小线程数
core size = "5"

//当那些超过coresize的任务完成后 存活时间
keep-alive = "5"

//当达到最大线程数时如何处理
rejection-policy  省缺为抛出TaskRejectedException异常,然后不执行

使用

异步方法

 @Async
    public void eventPlay(String uniPassportId,
                             String majorCode,
                             String courseCode,
                             String lessonCode,
                             String kpCode,
                             String videoCode,
                             String majorTitle,
                             String lessonTitle,
                             String stageTitle,
                             String kpTitle,
                             String videoPlayUrl,
                             String videoFileName,
                             String playCnt,
                             String playVideoTime) {

        PlayVideoRecordEntity record = new PlayVideoRecordEntity();
        record.setMajorCode(majorCode);
        record.setStageCode(courseCode);
        record.setLessonCode(lessonCode);
        record.setKpCode(kpCode);
        record.setVideoCode(videoCode);
        record.setMajorTitle(majorTitle);
        record.setLessonTitle(lessonTitle);
        record.setStageTitle(stageTitle);
        record.setKpTitle(kpTitle);
        record.setVideoPlayUrl(videoPlayUrl);
        record.setVideoFileName(videoFileName);
        record.setUniPassportId(uniPassportId);
        record.setPlayCnt(playCnt);
        record.setPlayTotalDuration(playVideoTime);
        event(record);

    }

原方法的调用片段

 if (StringUtils.equals(eventType, "videoStart")) {
                event.eventPlay(String.valueOf(userId), majorCode, stageCode, lessonCode, kpCode, videoCode, majorTitle, lessonTitle, stageTitle, kpTitle, videourl, videoFileName, "1", null);
            } else if (StringUtils.equals(eventType, "videoStop")) {
                event.eventPlay(String.valueOf(userId), majorCode, stageCode, lessonCode, kpCode, videoCode, majorTitle, lessonTitle, stageTitle, kpTitle, videourl, videoFileName, null, playVideoTime);
            }

返回值

@Async同样可以有返回值 类型为AsyncResult实现了Future接口

public void testAsyncAnnotationForMethodsWithReturnType()  
   throws InterruptedException, ExecutionException {  
    System.out.println("Invoking an asynchronous method. "  
      + Thread.currentThread().getName());  
    Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();  
   //循环扫描该异步方法的执行情况
    while (true) {  
    //用isDone来判断是否执行完毕
        if (future.isDone()) { 
        // 完毕输出
            System.out.println( future.get());  
            break;  
        }  
       Thread.sleep(1000);
    }  
}  

总结:这篇只是浅显的介绍,该注解涉及的问题还有很多,包括像异步情况下如何去处理异常问题,异步的情况下,无法捕捉到异步线程的异常,还有再异步的情况下如何去做事务的管理等等 。 以后用到了更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值