Java开启异步的两种方式
二、Java开启异步的两种方式
1、注解开启:@Async
1.1、配置异步的线程池
- 必须配置异步线程池,否则异步不会生效。
- @EnableAsync 注解:指定异步线程池。不指定默认使用:SimpleAsyncTaskExecutor线程池
- SimpleAsyncTaskExecutor是一个最简单的线程池,它没有任何的线程相关参数配置,它会为每个任务创建一个新的线程来执行,因此不建议在生产环境中使用。
- 配置线程池见:https://www.cnblogs.com/kakarotto-chen/p/17428432.html
package com.cc.md.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/** IO型的线程池
* @author CC
* @since 2023/5/23 0023
*/
@Configuration
@EnableAsync
public class IoThreadPool {
public static final int THREAD_SIZE = 2 * (Runtime.getRuntime().availableProcessors());
public static final int QUEUE_SIZE = 1000;
@Bean(name = "myIoThreadPool")
public ThreadPoolTaskExecutor threadPoolExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(THREAD_SIZE);
executor.setMaxPoolSize(THREAD_SIZE);
executor.setQueueCapacity(QUEUE_SIZE);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.setKeepAliveSeconds(60);
executor.setAllowCoreThreadTimeOut(true);
executor.setAwaitTerminationSeconds(300);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("myIo-Th-Pool-");
executor.initialize();
return executor;
}
}
1.2、异步方法
- 异步方法必须写在另一个类中,否则不生效
- @Async可以打在类上、也可以打在方法上
1 @Async:类上,说明整个类中的方法都是异步。必须写我们自己配置的线程池 —— ("myIoThreadPool")
2 @Async:方法上,说明这个方法是异步。不用写我们自己配置的线程池
- 异步接口+实现类
接口
package com.cc.md.service;
/**
* @author CC
* @since 2023/5/24 0024
*/
public interface IAsyncService {
/** 异步方法1
* @since 2023/5/24 0024
* @author CC
**/
void async1();
/** 异步方法2
* @since 2023/5/24 0024
* @author CC
**/
void async2();
}
实现类
package com.cc.md.service.impl;
import com.cc.md.service.IAsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/** 1 @Async:类上,说明整个类中的方法都是异步。必须写我们自己配置的线程池 —— ("myIoThreadPool")
* 2 @Async:方法上,说明这个方法是异步。不用写我们自己配置的线程池
* @author CC
* @since 2023/5/24 0024
*/
@Service
@Async("myIoThreadPool")
public class AsyncServiceImpl implements IAsyncService {
private static final Logger log = LoggerFactory.getLogger(AsyncServiceImpl.class);
//类上写了@Async,这里就可以不写了。
//可以不写 ("myIoThreadPool")。因为在IoThreadPool中开启了异步,说明异步用的就是我们配置的io线程池
//如果类上面打了 @Async ,这里必须写:("myIoThreadPool")
@Override
//@Async
public void async1(){
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", "异步方法1111!");
}
//@Async在类上面,说明这个方法也是异步方法。如果不打,无法开启异步。
@Override
public void async2(){
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", "异步方法2222!");
}
}
1.3、测试
@Resource
private IAsyncService asyncService;
//开启异步1 —— @Async
@Test
public void test03() throws Exception {
log.info("打印:{}", "异步测试的-主方法1");
asyncService.async1();
asyncService.async2();
//不会等待异步方法执行,直接返回前端数据
log.info("打印:{}", "异步测试的-主方法2");
}
结果:

2、CompletableFuture的方式
使用:
@Resource(name = "myIoThreadPool")
private ThreadPoolTaskExecutor myIoThreadPool;
//开启异步2 —— CompletableFuture.runAsync()
@Test
public void test04() throws Exception {
log.info("打印:{}", "异步测试的-主方法1");
CompletableFuture.runAsync(() -> {
log.info("打印:{}", "异步方法1!");
//异步执行的代码,也可以是方法,该方法不用单独写到其他类中。
this.async2("异步方法1!-end");
}, myIoThreadPool);
//不会等待异步方法执行,直接返回前端数据
log.info("打印:{}", "异步测试的-主方法2");
}
//异步需要执行的方法,可以写在同一个类中。
private void async2(String msg) {
//模仿io流耗时
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("打印:{}", msg);
}
结果:

- 后续CompletableFuture的使用见:《Java的CompletableFuture,Java的多线程开发》
Java开启异步的两种方式的更多相关文章
- 一步步分析Java深拷贝的两种方式-clone和序列化
今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...
- java笔记线程两种方式模拟电影院卖票
public class SellTicketDemo { public static void main(String[] args) { // 创建三个线程对象 SellTicket st1 = ...
- 创建Java多线程的两种方式和线程异常
一.使用多线程的两种方法 使用多线程的两种方法有:继承Thread类和实现runable接口. 二.继承Thread类 来看一下thread类的源代码: class Thread implement ...
- Java异常处理的两种方式以及自定义异常的使用方法
异常 就是程序出现了不正常的情况 Error:严重问题,不需要处理 Exception:称为异常类,他表示程序本身可以处理的问题 RuntimeException:在编译期是不检查的,出现问题后,需要 ...
- Java 和 数据库两种方式进行加锁
java方式: publicstatic synchronized int generate(StringtableName){ Stringsql = "select value from ...
- python进程开启的两种方式
一.进程 1.1.方式一 from multiprocessing import Process import time #方式一 def task(name): print(f"my na ...
- java判断数据类型两种方式
instanceof String s = ""; System.out.println(s instanceof String); // true simp ...
- Java多线程的两种实现方式
Java总共有两种方式实现多线程 方式1:通过继承Thread类的方式 package com.day04; /** * 通过继承Thread类并复写run方法来是实现多线程 * * @author ...
- 阿里巴巴--java多线程的两种实现方式,以及二者的区别
阿里巴巴面试的时候,昨天问了我java面试的时候实现java多线程的两种方式,以及二者的区别当时只回答了实现线程的两种方式,但是没有回答上二者的区别: java实现多线程有两种方式: 1.继承Thre ...
- 【java并发】传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...
随机推荐
- 01-【HAL库】STM32实现串口打印
一.什么是串口 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输 ...
- PicGo图床配置github仓库上传typora图片
(前提是已注册github并新建一个仓库作为你上传图片的位置) 首先在PicGo官网下载软件:https://picgo.github.io/PicGo-Doc/zh/ 打开typora,找到偏好设置 ...
- keycloak~在认证的action中自定义重定向地址
场景与实现逻辑 我的登录接口,在输入账号密码成功后进行中间页 中间页可以通过添加Authenticator的实现类来写逻辑 authenticate方法是渲染页面的,action方法是提交表单后的逻辑 ...
- Spring内存马分析
环境搭建 踩了很多坑....,不过还好最后还是成功了 IDEA直接新建javaEE项目,然后记得把index.jsp删了,不然DispatcherServlet会失效 导入依赖: <depend ...
- 微服务集成Spring Cloud Zipkin实现链路追踪并集成Dubbo
1.什么是ZipKin Zipkin 是一个根据 Google 发表的论文" Dapper" 进行开源实现的分布式跟踪系统. Dapper是Google 公司内部的分布式追踪系统, ...
- js推送网页到扩展屏上
需求: 电脑上有两个屏幕,想在主屏上的网页中点击一个按钮,副屏就可以显示需要推送过去的网页 实现方法: 本方法使用的是js来实现的,亲测可行,支持火狐,但是不支持谷歌 demo: 主屏网页:1.htm ...
- 实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking
实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking 论文url https://arxiv.org/abs/2003.11753 论文简述: ...
- HarmonyOS应用事件打点开发指导
简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志,难以识别其中的关键信息.因此,应用开发者需要一种数据打点机制,用来评估如访问数.日活.用户操作习惯以及影响用户使用的关键因素等关键 ...
- 第二十一篇:信号、缓存、中间件、Form操作
一.CSRF 二.中间件 三.缓存 四.信号 五.Form操作
- 面向切面编程AOP[二](java @EnableAspectJAutoProxy 代码原理)
前言 @EnableAspectJAutoProxy 是启动aop功能的意思,那么里面是什么呢? 正文 @Target({ElementType.TYPE}) @Retention(Retention ...