使用SpringBoot的@Async实现异步调用方法,以及自己开启新线程异步调用

使用SpringBoot的@Async实现异步调用方法,以及自己开启新线程异步调用一.springboot的@Async注解实现异步要在springboot中使用异步调用方法,只要在被调用的方法上面加上@Async就可以了1.准备工作准备一个springboot工程,在Application类上加上EnableAsync注解开启异步/***@Author:zgd*@Date:18/09/1210:27*@Description:…

大家好,又见面了,我是你们的朋友全栈君。

Page Counter

一. springboot的@Async注解实现异步

要在springboot中使用异步调用方法,只要在被调用的方法上面加上@Async就可以了

1.准备工作

准备一个springboot工程,在Application类上加上EnableAsync注解开启异步

/** * @Author: zgd * @Date: 18/09/12 10:27 * @Description: */
@SpringBootApplication
@EnableAsync
public class Application { 
   

  public static void main(String[] args) { 
   
    SpringApplication.run(Application.class,args);
  }

}

这个注解如果不加,@Async注解失效

2.controller

写一个同步接口和异步接口

package com.zgd.demo.thread.asyn.controller;

import com.zgd.demo.thread.asyn.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Instant;

/** * @Author: zgd * @Date: 18/09/12 10:26 * @Description: hello */
@RestController
@RequestMapping("/hello")
public class HelloController { 
   

  @Autowired
  private HelloService helloService;

  /** * 异步方法 * @return */
  @RequestMapping("/asyn")
  public String getAsynHello(){ 
   
    long n = Instant.now().toEpochMilli();
    //异步
    String s = helloService.asynchSayHello();

    long f = Instant.now().toEpochMilli();
    return s + " 时间: " + (f-n);

  }

  /** * 同步方法 * * @return */
  @RequestMapping("/sync")
  public String getSyncHello(){ 
   

    long n = Instant.now().toEpochMilli();
    //异步
    String s = helloService.synchSayHello();

    long f = Instant.now().toEpochMilli();
    return s + " 时间: " + (f-n);
  }
}

3.helloService

写一个HelloService接口,并实现该接口

package com.zgd.demo.thread.asyn.service.impl;

import com.zgd.demo.thread.asyn.service.HelloService;
import com.zgd.demo.thread.asyn.service.SleepService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/** * @Author: zgd * @Date: 18/09/12 10:43 * @Description: */
@Service
public class HelloServiceImpl implements HelloService { 
   

  @Autowired
  private SleepService sleepService;

  @Override
  public String synchSayHello() { 
   
    try { 
   
      sleepService.syncSleep();
      return "hello world,这是同步方法";
    } catch (InterruptedException e) { 
   
      e.printStackTrace();
      return "error";
    }
  }

  @Override
  public String asynchSayHello() { 
   
    try { 
   
      System.out.println("主线程 "+Thread.currentThread().getName());
      sleepService.asyncSleep();
      return "hello world,这是异步方法";
    } catch (InterruptedException e) { 
   
      e.printStackTrace();
      return "error";
    }
  }
}

这里为了模拟应用场景,将耗时的方法放在另一个service里面,就叫SleepService,同样的,实现这个接口

package com.zgd.demo.thread.asyn.service.impl;

import com.zgd.demo.thread.asyn.service.SleepService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/** * @Author: zgd * @Date: 18/09/12 10:46 * @Description: */
@Service
public class SleepServiceImpl implements SleepService { 
   

  @Override
  public void syncSleep() throws InterruptedException { 
   
    System.out.println("线程名: " +Thread.currentThread().getName());
    System.out.println("开始同步休眠3秒");
    Thread.sleep(3000);
    System.out.println("同步休眠结束");
  }

  @Override
  @Async
  public void asyncSleep() throws InterruptedException { 
   
    System.out.println("次线程 "+Thread.currentThread().getName());

    System.out.println("开始异步休眠3秒");
    Thread.sleep(3000);
    System.out.println("异步休眠休眠结束");
  }
}

两个方法都是休眠3秒,aysncSleep方法上面有一个@Async注解

4.测试

  • 同步
    访问 http://localhost:8080/hello/sync
    在这里插入图片描述
    控制台
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpLDV4Mc-1587893525642)(https://i.imgur.com/aICMDZA.png)]
    要3秒的时间才能收到响应

  • 异步
    访问 http://localhost:8080/hello/asyn
    在这里插入图片描述
    在这里插入图片描述
    可见主线程和次线程打印出来的线程名不一样,也就是springboot帮我们开启了一个线程去处理

注意事项

  1. 必须要加@EnableAsync注解
  2. 不能在同一类下调用@Async注解的方法,比如A类下有a和b方法,b方法有@Async注解,不能直接这样a调用b,要把b放到其他类中
  3. @Async也可以打在类上,这样类下面的所有方法都是异步的(被其他类调用的时候)

二.开启线程实现异步

如果我们没有使用springboot,使用传统的方法怎么异步调用方法?还是开启一个新的线程

1.controller

增加一个接口

/** * 同步方法 * * @return */
  @RequestMapping("/thread/asyn")
  public String getThreadSyncHello(){ 
   
    long n = Instant.now().toEpochMilli();
    //异步
    String s = helloService.threadAsynchSayHello();
    long f = Instant.now().toEpochMilli();
    return s + " 时间: " + (f-n);
  }

2.service

HelloServiceImpl

@Override
  public String threadAsynchSayHello() { 
   
    //还是休眠3秒
    Runnable runnable = ()-> { 
   
      try { 
   
        sleepService.syncSleep();
      } catch (InterruptedException e) { 
   
        e.printStackTrace();
      }
    };
    System.out.println(Thread.currentThread().getName()+" 开启新线程");
    new Thread(runnable).start();
    return "hello world,这是开启线程的异步方法";
  }

3.测试

我们访问 http://localhost:8080/hello/thread/asyn
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqsAimN4-1587893525654)(https://i.imgur.com/huTAJAm.png)]

在这里插入图片描述

同样的两个线程名不一样,开启了一个新线程处理,并且多次测试可以看出,自己直接开启线程比@Async要快几毫秒,不过可以忽略不计了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157522.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网络协议、socket、webSocket

    网络协议、socket、webSocket一、网络协议网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。1、OSI七层协议OSI是一个开放性的通信系统互连参考模型,他是一个定义得非常好的协议规范。OSI模型有7层结构,从上到下分别是7应用层6表示层5会话层4传输层3网络层2数据链路层1物理层。下面的图表显示不同的协议在最初OSI模型中的位置:7应用层例如HTTP、SMTP…

    2022年5月2日
    43
  • cuda编程基础(编程软件有哪些)

    CUDA(ComputeUnifiedDeviceArchitecture),是显卡厂商NVIDIA推出的运算平台。CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。

    2022年4月18日
    49
  • JMESPath_pathparam注解

    JMESPath_pathparam注解前言JMESPath是JSON的查询语言。您可以从JSON文档中提取和转换元素官方文档:https://jmespath.org/tutorial.html基本表达式JMESPath用的最多的

    2022年8月6日
    13
  • JAVA课程设计——飞机大战(个人)

    JAVA课程设计——飞机大战(个人)

    2021年10月6日
    62
  • mac datagrip2021.4激活码_通用破解码

    mac datagrip2021.4激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
    100
  • 一定要看

    一定要看前言(一定要看)首先说一下啊,本人是个菜鸟,但自认是一个懂的上进的菜鸟,现在对游戏开发或多或少懂了一丁点吧。现在把我的资料全部上传,也许大家会觉得,资料有的网上都有吧,也许觉得资料没什么用吧,这个确实。但一个资料只要有一点点对你有用我就满意了,就够了。为了方便大家下载,小文件我都是打包了,没有任何的密码之类的。学习的资料不管是好的还是不好的我都上传了,这些是我从0开始学的东

    2022年7月16日
    15

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号