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

来源:互联网 发布:青年网络公开课主持人 编辑:程序博客网 时间:2024/06/05 13:23

使用需求

在开发中,我们往往有一些特殊的需求,例如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);    }  }  

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

原创粉丝点击