@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 ...
随机推荐
- 《Linux基础》07. 软件管理
@ 目录 1:软件管理 1.1:rpm 1.1.1:查询 1.1.2:卸载 1.1.3:安装 1.2:yum 1.3:dpkg 1.4:apt 1.4.1:相关配置 1.4.2:常用指令 1.4.3: ...
- 2.12 PE结构:实现PE字节注入
本章笔者将介绍一种通过Metasploit生成ShellCode并将其注入到特定PE文件内的Shell注入技术.该技术能够劫持原始PE文件的入口地址,在PE程序运行之前执行ShellCode反弹,执行 ...
- .NET使用quartz+topshelf实现定时执行任务调度服务
一.项目开发 1.新建控制台应用(.NET Framework) 2.配置新项目,自行修改项目名称.位置和框架(建议使用.NET Framework4.5以上版本) 创建好的项目目录如下: 3.右键引 ...
- 如何在.NET电子表格应用程序中创建流程图
前言 流程图是一种常用的图形化工具,用于展示过程中事件.决策和操作的顺序和关系.它通过使用不同形状的图标和箭头线条,将任务和步骤按照特定的顺序连接起来,以便清晰地表示一个过程的执行流程. 在企业环境中 ...
- Solution -「洛谷 P1852」跳跳棋
Description Link. 在一个数轴上给你三个点,移动方法是彼此为中点进行跳跃,不能同时越过两颗棋子. 给出初始状态和目标状态,问能否从初始状态跳到目标状态.若能,输出最少步数. 棋子之间互 ...
- OPPO主题组件开发 - 调试与预览
本篇作为 OPPO主题组件调试与预览 文档的补充,因为它真的很简单而且太老,一些命令已发生变化 1. 调试前准备 1. PC 端下载 adb命令工具 下载 https://adbdownload.co ...
- Java 21新特性:Sequenced Collections(有序集合)
在JDK 21中,Sequenced Collections的引入带来了新的接口和方法来简化集合处理.此增强功能旨在解决访问Java中各种集合类型的第一个和最后一个元素需要非统一且麻烦处理场景. 下面 ...
- Abp vNext 依赖注入
文章目录 介绍 ABP的依赖注入系统是基于Microsoft的依赖注入扩展库(Microsoft.Extensions.DependencyInjection nuget包)开发的.所以我们采用dot ...
- C#学习笔记--逻辑语句(分支和循环)
逻辑语句 条件分支语句 条件分支语句可以让顺序执行的代码逻辑产生分支,满足对应条件地执行对应代码逻辑. IF语句 //IF语句块 int a=5; if(a>0&&a<15 ...
- 这款 7k Star 的国产监控系统,真不错!
我们都知道天下没有"永不宕机"的系统,但每次线上出问题都要拉出一个程序员"祭天".所以一款靠谱.好用的监控工具就显得十分重要,它可以在生产环境出故障的第一时间发 ...