spring注解之@Async

版权声明:本文为博主原创文章,转载请注明原文链接哦,forethought.top! https://blog.csdn.net/qq_36922927/article/details/84940096

这个注解看着Async应该可以猜测用途,那就是异步。

这个注解是用来将某个被标注的方法给弄成异步的效果,达到new  Thread的作用,

博主也赶紧拿来了代码测试。

异步我最先是在js学习时,ajax提交那里第一次接触,有一个async属性,来设置这个ajax是异步还是同步。

如下伪代码所示:

$(function(){


$.ajax({//1

async;true//设置为异步,代码应该不对,意思是这样
})

do something else;//2



});

js里的异步,就是这里的不需要ajax的请求得到返回结果,就可以执行2

而如果是同步,则是这里的async=false,必须ajax请求得到返回结果才能执行2

我就类比这里的ajax,认为@Async也是这个含义(经过试验,这是错误的猜测)

测试不使用@Async

controller:

  @RequestMapping("/async")
    public Object  testAsync(String param){
System.out.println("controller 开始:"+new Timestamp(System.currentTimeMillis())+" "+param+ " thread:"+Thread.currentThread());
//开始异步方法执行
    userService.async();
    System.out.println("controller 返回 "+new Timestamp(System.currentTimeMillis())+"thread :"+Thread.currentThread());
      return  "finished";
    }

service方法:


    public  void  async(){
       long now=System.currentTimeMillis();
       int count=0;
       while (true){
          if(count++==0){
              System.out.println(System.currentTimeMillis()+" thread:"+Thread.currentThread());
          }

          if(System.currentTimeMillis()-5000>now){
               System.out.println("异步方法:执行完成"+new Timestamp(System.currentTimeMillis())+ " thread:"+Thread.currentThread());
               break;
           }
       }
    }

5秒内调用两次接口:

测试结果:

// @Async
 controller 开始:2018-12-10 09:35:12.472 1 thread:Thread[http-nio-8011-exec-1,5,main]// 第一次调用
1544405712472 thread:Thread[http-nio-8011-exec-1,5,main]// 第一次调用
controller 开始:2018-12-10 09:35:13.863 1 thread:Thread[http-nio-8011-exec-2,5,main]//第二次调用
1544405713863 thread:Thread[http-nio-8011-exec-2,5,main]//第二次调用
异步方法:执行完成2018-12-10 09:35:17.473 thread:Thread[http-nio-8011-exec-1,5,main]// 第一次调用
controller 返回 2018-12-10 09:35:17.473thread :Thread[http-nio-8011-exec-1,5,main]// 第一次调用
异步方法:执行完成2018-12-10 09:35:18.864 thread:Thread[http-nio-8011-exec-2,5,main]//第二次调用
controller 返回 2018-12-10 09:35:18.864thread :Thread[http-nio-8011-exec-2,5,main]//第二次调用

结果说明什么:(按时间顺序)

第一次进入controller

第一次进入sync方法

第二次进入controller

第二次进入async方法

第一次退出async方法

第一次退出controller

第二次退出async方法

第二次退出controller

实验推论(现象)

上述结果说明service的async方法没有被第一个线程独占,即第一下线程还在async方法中时,第二个也能同时进入。

 并且controller方法的返回是出现在对应次的async方法退出之后再退出controller

但是这里的同步应该不是指async被线程独占,而是指  每次请求都是进入controller-》进入async方法-》退出async方法-》退出controller

使用@Async注解

需要注意的是:springboot需要在启动类上标注 @EnableAsync ,不然是不生效的

service方法:

@Async
    public  void  async(){
       long now=System.currentTimeMillis();
       int count=0;
       while (true){
          if(count++==0){
              System.out.println(System.currentTimeMillis()+" thread:"+Thread.currentThread());
          }

          if(System.currentTimeMillis()-5000>now){
               System.out.println("异步方法:执行完成"+new Timestamp(System.currentTimeMillis())+ " thread:"+Thread.currentThread());
               break;
           }
       }
    }

效果:

controller 开始:2018-12-10 15:25:42.739 1 thread:Thread[http-nio-8011-exec-1,5,main]
controller 返回 2018-12-10 15:25:42.743thread :Thread[http-nio-8011-exec-1,5,main]
1544426742747 thread:Thread[task-1,5,main]
异步方法:执行完成2018-12-10 15:25:47.748 thread:Thread[task-1,5,main]


controller 开始:2018-12-10 15:25:48.602 1 thread:Thread[http-nio-8011-exec-3,5,main]
controller 返回 2018-12-10 15:25:48.602thread :Thread[http-nio-8011-exec-3,5,main]
1544426748603 thread:Thread[task-2,5,main]
异步方法:执行完成2018-12-10 15:25:53.604 thread:Thread[task-2,5,main]

发现了,的确是先完成了controller方法,而async方法还在继续,和js的ajax的异效果是一致的。

对比结论:

与不使用@Asyn对比发现;

不使用@Async:线程名字是: thread:Thread[http-nio-8011-exec-1,5,main]  是thread

使用@Async:线程名字是:1544426742747 thread:Thread[task-1,5,main]  是 task(多核线程,查看jdk源码定义,这个可以用来更新进度条的的作用,这里就不纠结了,是线程)

上面两种情况观察发现:

1,@Async达到的异步效果是ajax的那样

2,@Async开启了线程(Task)

猜你喜欢

转载自blog.csdn.net/qq_36922927/article/details/84940096