使用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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • container_of宏定义作用_宏内核

    container_of宏定义作用_宏内核内核链表是怎么通过指针域来访问数据域的呢?

    2022年8月22日
  • 什么是网站的灵魂_测试性能网站

    什么是网站的灵魂_测试性能网站前言在前一篇随笔《大型网站系统架构的演化》中,介绍了大型网站的演化过程,期间穿插了一些技术和手段,我们可以从中看出一个大型网站的轮廓,但想要掌握设计开发维护大型网站的技术,需要我们一步一步去研究实践

    2022年8月4日
  • Werkzeug框架

    Werkzeug框架在我们使用Flask以及Werkzeug框架的过程中,经常会遇到如下三个概念:Local、LocalStack和LocalProxy。尤其在学习Flask的RequestContext和AppContext的过程中,这几个概念出现的更加频繁,另外很多Flask插件都会使用这三个概念对应的技术。那么这三个东西到底是什么?我们为什么需要它们?以及如何使用呢?本篇文章主要就是来解答这些问题。…

    2022年10月6日
  • SqlSession和SqlSessionFactory「建议收藏」

    SqlSession和SqlSessionFactory「建议收藏」SqlSessionFactoryBuilder  这个类可以被实例化、使用和丢弃,一旦创建了SqlSessionFactory,就不再需要它了。因此SqlSessionFactoryBuilder实例的最佳范围是方法范围(也就是局部方法变量)。你可以重用SqlSessionFactoryBuilder来创建多个SqlSessionFactory实例,但是最好还是不要让其一…

    2022年4月30日
  • Windows server2012密钥_windows 7密钥

    Windows server2012密钥_windows 7密钥WindowsServer2012Standard密钥:NB4WH-BBBYV-3MPPC-9RCMV-46XCBWindowsServer2012StandardCore密钥:NB4WH-BBBYV-3MPPC-9RCMV-46XCBWindowsServer2012Datacenter密钥:BH9T4-4N7CW-67J3M-64J36-WW98YWindowsS

    2022年10月10日
  • 全国职称计算机考试取消了吗,全国职称计算机考试取消必考模块 考生自选[通俗易懂]

    全国职称计算机考试取消了吗,全国职称计算机考试取消必考模块 考生自选[通俗易懂]全国职称计算机考试不再设必考模块,考生可选择自己擅长的模块进行考试。本月起,鞍山专业技术人员计算机应用能力考试系统将进行升级。调整后的题库中共有20个考试模块供考生选择报考。此前,职称计算机考试要设一个必考模块,调整后取消必考项目,考生可自主选择两个模块作为应考模块。据介绍,调整后的20个模块分别为:中文WindowsXP操作系统、Word2003中文字处理、Excel2003中文电子表格、Pow…

    2022年6月2日

发表回复

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

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