使用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要快几毫秒,不过可以忽略不计了

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Python中如何求列表list的平均数[通俗易懂]

    Python中如何求列表list的平均数当列表list中只包含数字时,如何求取它的平均数:fromnumpyimport*a=[52,69,35,65,89,15,34]b=mean(a)print(b)运行结果:51.285714285714285…

  • css实现返回顶部,实现返回顶部效果

    css实现返回顶部,实现返回顶部效果实现的效果如下可以点击它返回到首页去html部分title=”返回顶部”>css部分.layui-fixbar{position:fixed;right:15px;bottom:15px;z-index:999999;right:50px;bottom:50px;height:50px;list-style:none;}.layui-fixbar.layui-fixba…

  • mac视频录制工具推荐[通俗易懂]

    mac视频录制工具推荐[通俗易懂]AVAideScreenRecorderforMac是一款mac视频录制工具,可帮助用户可以选择录制整个屏幕或自定义区域,支持声音的同步录制,以1080p等高清质量以高达60fps的速度录制屏幕活动、视频和游戏。它可以让您以无损质量处理所有屏幕录制任务,包括Zoom会议、视频通话、文件、在线课程等。除了屏幕捕获之外,我们的屏幕录像机还可以作为一个令人难以置信的音频和声音和录音机,将您的录音提升到一个新的水平。任何希望为音乐制作、音频笔记或其他任何东西创建专业品质音频的人都可

  • NGINX.conf配置文件支持pathinfo

    NGINX.conf配置文件支持pathinfo

  • igmp是负责ip组播成员管理的协议_IGMP协议

    igmp是负责ip组播成员管理的协议_IGMP协议组播协议分为主机-路由器之间的组成员关系协议和路由器-路由器之间的组播路由协议。组成员关系协议包括IGMP(互连网组管理协议)。组播路由协议分为域内组播路由协议及域间组播路由协议。域内组播路由协议包括PIM-SM、PIM-DM、DVMRP等协议,域间组播路由协议包括MBGP、MSDP等协议。IGMP(InternetGroupManagementProtocol)作为因特网组管理协议,是TCP/IP协议族中负责IP组播成员管理的协议,它用来在IP主机和与其直接相邻的组播路由器之间建立、维护组播组成员关

  • SVNclient安装与使用

    SVNclient安装与使用

发表回复

您的电子邮箱地址不会被公开。

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