@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 ...
随机推荐
- API接口的设计思路
API接口设计是软件开发中非常重要的一环,良好的设计规范能够提高开发效率.减少问题和错误,并增强系统的可维护性和可扩展性.本文从程序员的视角,讨论一些常见的API接口设计规范. 一.遵循RESTf ...
- 白盒AES和SM4实现的差分故障分析
DFA攻击背景介绍 传统的密码安全性分析环境被称为黑盒攻击环境,攻击者只能访问密码系统的输入与输出,但随着密码系统部署环境的多样化,该分析模型已经不能够反映实际应用中攻击者的能力.2002年,Chow ...
- Iphone通过ssh进行访问
Iphone通过usb进行ssh访问文件系统 在公司里wifi很不给力,而我又想通过ssh访问我的iphone,进行一些权限访问,这时我们该 itunnel_mux_rev71这个工具可以帮我们的忙 ...
- 【RocketMQ】【源码】延迟消息实现原理
RocketMQ设定了延迟级别可以让消息延迟消费,延迟消息会使用SCHEDULE_TOPIC_XXXX这个主题,每个延迟等级对应一个消息队列,并且与普通消息一样,会保存每个消息队列的消费进度(dela ...
- 用Rust手把手编写一个Proxy(代理), 动工
用Rust手把手编写一个Proxy(代理), 动工 项目 ++wmproxy++ gitee 传送门 github 传送门 设计流程图 flowchart LR A[客户端] -->|Http| ...
- Docker Swarm + Harbor + Portainer 打造高可用,高伸缩,集群自动化部署,更新。
Docker Swarm是Docker官方自带的容器编排工具,Swarm,Compose,Machine合称Docker三剑客.Docker Swarm对于中小型应用来说,还是比较方便,灵活,当然K8 ...
- Java 21 新特性:虚拟线程(Virtual Threads)
在Java 21中,引入了虚拟线程(Virtual Threads)来简化和增强并发性,这使得在Java中编程并发程序更容易.更高效. 虚拟线程,也称为"用户模式线程(user-mode t ...
- C++中::和:, .和->的作用和区别
符号::和:的作用和区别 ::是作用域运算符,A::B表示作用域A中的-名称B,A可以是名字空间.类.结构: 类作用域操作符 "::"指明了成员函数所属的类.如:M::f(s)就表 ...
- MySQL系列之备份恢复——运维在备份恢复方面、备份类型、备份方式及工具、逻辑备份和物理备份、备份策略、备份工具使用-mysqldump、企业故障恢复案例、备份时优化参数、MySQL物理备份工具
文章目录 1. 运维在数据库备份恢复方面的职责 1.1 设计备份策略 1.2 日常备份检查 1.3 定期恢复演练(测试库) 1.4 故障恢复 1.5 迁移 2. 备份类型 2.1 热备 2.2 温备 ...
- Full Tank 题解
Full Tank 题目大意 给定一张 \(n\) 个点,\(m\) 条边的连通无向图,在每个点有一个加油站,油价为该点的点权,每条边的油耗为该边的边权.现给出若干询问,问一辆油箱容量为 \(c\) ...