@Async实现异步任务
1、@Async是SpringBoot自带的一个执行步任务注解
@EnableAsync // 开启异步
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2、同步执行
定义几个方法,模拟耗时的操作
@Service
@Slf4j
public class ServiceDemoSync {
public void taskOne() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
}
public void taskTwo() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
}
public void taskThere() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}
测试一下
/**
* @author qbb
*/
@SpringBootTest
public class ServiceTestSync {
@Autowired
private ServiceDemoSync serviceDemoSync;
@Test
public void test01() throws Exception {
long start = System.currentTimeMillis();
serviceDemoSync.taskOne();
serviceDemoSync.taskTwo();
serviceDemoSync.taskThere();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}

3、异步执行
@Service
@Slf4j
public class ServiceDemo {
@Async
public void taskOne() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
}
@Async
public void taskTwo() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
}
@Async
public void taskThere() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}
@SpringBootTest
public class ServiceTest {
@Autowired
private ServiceDemo serviceDemo;
@Test
public void test01() throws Exception {
long start = System.currentTimeMillis();
serviceDemo.taskOne();
serviceDemo.taskTwo();
serviceDemo.taskThere();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}

4、使用自定义线程池
package com.qbb.service;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 自定义线程池
*/
@Configuration
public class ExecutorAsyncConfig {
@Bean(name = "newAsyncExecutor")
public Executor newAsync() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 设置核心线程数
taskExecutor.setCorePoolSize(2);
// 线程池维护线程的最大数量,只有在缓冲队列满了以后才会申请超过核心线程数的线程
taskExecutor.setMaxPoolSize(10);
// 缓存队列
taskExecutor.setQueueCapacity(2);
// 允许的空闲时间,当超过了核心线程数之外的线程在空闲时间到达之后会被销毁
taskExecutor.setKeepAliveSeconds(10);
// 异步方法内部线程名称
taskExecutor.setThreadNamePrefix("QIUQIU&LL-AsyncExecutor-");
// 拒绝策略
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.initialize();
return taskExecutor;
}
}
定义线程任务
@Component
@Slf4j
public class FutureTaskExecutor {
@Async(value = "newAsyncExecutor")
public Future<String> taskOne() {
return new AsyncResult<>(Thread.currentThread().getName() + "one 完成");
}
@Async(value = "newAsyncExecutor")
public Future<String> taskTwo() {
return new AsyncResult<>(Thread.currentThread().getName() + "two 完成");
}
@Async
public Future<String> taskThree() {
return new AsyncResult<>(Thread.currentThread().getName() + "three 完成");
}
}
测试一下
/**
* @author qbb
*/
@SpringBootTest
@Slf4j
public class FutureTaskTestExecutor {
@Autowired
private FutureTaskExecutor futureTaskExecutor;
@Test
public void runAsync() throws Exception {
long start = System.currentTimeMillis();
Future<String> taskOne = futureTaskExecutor.taskOne();
Future<String> taskTwo = futureTaskExecutor.taskTwo();
Future<String> taskThere = futureTaskExecutor.taskThree();
while (true) {
if (taskOne.isDone() && taskTwo.isDone() && taskThere.isDone()) {
System.out.println("任务1返回结果={" + (taskOne.get()) + "},任务2返回结果={" + (taskTwo.get()) + "},任务3返回结果={" + (taskThere.get()) + "}");
break;
}
}
long end = System.currentTimeMillis();
System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}

注意点:不生效的情况
1、@Async作用在static修饰的方法上不生效

2、调用异步任务的方法和异步方法在同一个类时不生效
@Service
@Slf4j
public class ServiceDemo {
@Async
public void taskOne() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
}
@Async
public void taskTwo() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
}
@Async
public void taskThere() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
}
@Test
public void test01() throws Exception {
long start = System.currentTimeMillis();
taskOne();
taskTwo();
taskThere();
Thread.sleep(200);
long end = System.currentTimeMillis();
System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
}
}

还是推荐使用CompletableFuture实现异步任务编排~~
@Async实现异步任务的更多相关文章
- ASP.NET sync over async(异步中同步,什么鬼?)
async/await 是我们在 ASP.NET 应用程序中,写异步代码最常用的两个关键字,使用它俩,我们不需要考虑太多背后的东西,比如异步的原理等等,如果你的 ASP.NET 应用程序是异步到底的, ...
- HTML5中script的async属性异步加载JS
HTML5中script的async属性异步加载JS HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...
- spring boot中使用@Async实现异步调用任务
本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...
- async/await异步处理demo
async/await异步处理demo 下载地址: async/await异步处理demo
- Promise,Generator(生成器),async(异步)函数
Promise 是什么 Promise是异步编程的一种解决方案.Promise对象表示了异步操作的最终状态(完成或失败)和返回的结果. 其实我们在jQuery的ajax中已经见识了部分Promise的 ...
- spring boot 学习(十一)使用@Async实现异步调用
使用@Async实现异步调用 什么是”异步调用”与”同步调用” “同步调用”就是程序按照一定的顺序依次执行,,每一行程序代码必须等上一行代码执行完毕才能执行:”异步调用”则是只要上一行代码执行,无需等 ...
- 【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
- 将 async/await 异步代码转换为安全的不会死锁的同步代码
在 async/await 异步模型(即 TAP Task-based Asynchronous Pattern)出现以前,有大量的同步代码存在于代码库中,以至于这些代码全部迁移到 async/awa ...
- Spring @Async开启异步任务
1. 开启异步 @SpringBootApplication @EnableAsync //开启异步任务 public class Application { @Bean(name="pro ...
- Spring Boot使用@Async实现异步调用
原文:http://blog.csdn.net/a286352250/article/details/53157822 项目GitHub地址 : https://github.com/FrameRes ...
随机推荐
- CTFshow misc1-10
小提示:需要从图片上提取flag文字,可以通过截图翻译或者微信发送图片,这两个的ai图像识别挺好用的. misc1: 解压打开就能看见flag,提取出来就行 misc2: 记事本打开,看见 ng字符, ...
- 如何调用API接口获取淘宝商品数据
淘宝商品数据的获取是一项非常重要的技术,它可以为淘宝卖家和买家提供有利的数据分析和扩展市场的机会.调用API接口是一种快速.方便.高效的方式获取淘宝商品数据. 以下是一些步骤来调用API接口来获取淘宝 ...
- pandas常用的数据类型,(serises和dataform)
- Ubuntu22.04 编译安装nginx
1.下载nginx软件包 https://nginx.org/en/download.html 2.压缩包上传服务器并解压缩 tar xf nginx-1.22.1.tar.gz 3.进入解压目录,编 ...
- jenkins更换国内插件源
sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' ...
- gitbook生成静态页面不跳转
gitbook页面不跳转 现在可以在localhost:4000/查看自己的网页了.而且生成的网页存在_book文件夹中,下次点击 _book文件夹中的index.html就能打开网页,内容无更新,就 ...
- win11系统无法解决的死结
如果需要使用网上银行.win11一定不能使用. win11已经取消了,对于IE浏览器的支持和安装. 但是大部分网银都是要求IE浏览器.或者IE内核.实际过程当中.虽然所有的浏览器都说兼容IE有IE内核 ...
- C++在HotSpot VM中一种巧妙的内存管理方式
在HotSpot VM中定义了一个Relocation类及相关的子类,可以通过这些类操作不同的重定位数据,如在CodeCache中读写这些数据.这些类需要的内存很小,但是不同的类需要的内存大小又不一样 ...
- 深入探讨I/O模型:Java中的阻塞和非阻塞和其他高级IO应用
引言 I/O(Input/Output)模型是计算机科学中的一个关键概念,它涉及到如何进行输入和输出操作,而这在计算机应用中是不可或缺的一部分.在不同的应用场景下,选择正确的I/O模型是至关重要的,因 ...
- Vue之基础事件
1.基础事件,先弹框试试 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...