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实现异步任务的更多相关文章

  1. ASP.NET sync over async(异步中同步,什么鬼?)

    async/await 是我们在 ASP.NET 应用程序中,写异步代码最常用的两个关键字,使用它俩,我们不需要考虑太多背后的东西,比如异步的原理等等,如果你的 ASP.NET 应用程序是异步到底的, ...

  2. HTML5中script的async属性异步加载JS

    HTML5中script的async属性异步加载JS     HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...

  3. spring boot中使用@Async实现异步调用任务

    本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...

  4. async/await异步处理demo

    async/await异步处理demo 下载地址: async/await异步处理demo

  5. Promise,Generator(生成器),async(异步)函数

    Promise 是什么 Promise是异步编程的一种解决方案.Promise对象表示了异步操作的最终状态(完成或失败)和返回的结果. 其实我们在jQuery的ajax中已经见识了部分Promise的 ...

  6. spring boot 学习(十一)使用@Async实现异步调用

    使用@Async实现异步调用 什么是”异步调用”与”同步调用” “同步调用”就是程序按照一定的顺序依次执行,,每一行程序代码必须等上一行代码执行完毕才能执行:”异步调用”则是只要上一行代码执行,无需等 ...

  7. 【转】C# Async/Await 异步编程中的最佳做法

    Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...

  8. 将 async/await 异步代码转换为安全的不会死锁的同步代码

    在 async/await 异步模型(即 TAP Task-based Asynchronous Pattern)出现以前,有大量的同步代码存在于代码库中,以至于这些代码全部迁移到 async/awa ...

  9. Spring @Async开启异步任务

    1. 开启异步 @SpringBootApplication @EnableAsync //开启异步任务 public class Application { @Bean(name="pro ...

  10. Spring Boot使用@Async实现异步调用

    原文:http://blog.csdn.net/a286352250/article/details/53157822 项目GitHub地址 : https://github.com/FrameRes ...

随机推荐

  1. API接口的设计思路

    ​ API接口设计是软件开发中非常重要的一环,良好的设计规范能够提高开发效率.减少问题和错误,并增强系统的可维护性和可扩展性.本文从程序员的视角,讨论一些常见的API接口设计规范. 一.遵循RESTf ...

  2. 白盒AES和SM4实现的差分故障分析

    DFA攻击背景介绍 传统的密码安全性分析环境被称为黑盒攻击环境,攻击者只能访问密码系统的输入与输出,但随着密码系统部署环境的多样化,该分析模型已经不能够反映实际应用中攻击者的能力.2002年,Chow ...

  3. Iphone通过ssh进行访问

    Iphone通过usb进行ssh访问文件系统 在公司里wifi很不给力,而我又想通过ssh访问我的iphone,进行一些权限访问,这时我们该 itunnel_mux_rev71这个工具可以帮我们的忙 ...

  4. 【RocketMQ】【源码】延迟消息实现原理

    RocketMQ设定了延迟级别可以让消息延迟消费,延迟消息会使用SCHEDULE_TOPIC_XXXX这个主题,每个延迟等级对应一个消息队列,并且与普通消息一样,会保存每个消息队列的消费进度(dela ...

  5. 用Rust手把手编写一个Proxy(代理), 动工

    用Rust手把手编写一个Proxy(代理), 动工 项目 ++wmproxy++ gitee 传送门 github 传送门 设计流程图 flowchart LR A[客户端] -->|Http| ...

  6. Docker Swarm + Harbor + Portainer 打造高可用,高伸缩,集群自动化部署,更新。

    Docker Swarm是Docker官方自带的容器编排工具,Swarm,Compose,Machine合称Docker三剑客.Docker Swarm对于中小型应用来说,还是比较方便,灵活,当然K8 ...

  7. Java 21 新特性:虚拟线程(Virtual Threads)

    在Java 21中,引入了虚拟线程(Virtual Threads)来简化和增强并发性,这使得在Java中编程并发程序更容易.更高效. 虚拟线程,也称为"用户模式线程(user-mode t ...

  8. C++中::和:, .和->的作用和区别

    符号::和:的作用和区别 ::是作用域运算符,A::B表示作用域A中的-名称B,A可以是名字空间.类.结构: 类作用域操作符 "::"指明了成员函数所属的类.如:M::f(s)就表 ...

  9. MySQL系列之备份恢复——运维在备份恢复方面、备份类型、备份方式及工具、逻辑备份和物理备份、备份策略、备份工具使用-mysqldump、企业故障恢复案例、备份时优化参数、MySQL物理备份工具

    文章目录 1. 运维在数据库备份恢复方面的职责 1.1 设计备份策略 1.2 日常备份检查 1.3 定期恢复演练(测试库) 1.4 故障恢复 1.5 迁移 2. 备份类型 2.1 热备 2.2 温备 ...

  10. Full Tank 题解

    Full Tank 题目大意 给定一张 \(n\) 个点,\(m\) 条边的连通无向图,在每个点有一个加油站,油价为该点的点权,每条边的油耗为该边的边权.现给出若干询问,问一辆油箱容量为 \(c\) ...