二、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开启异步的两种方式的更多相关文章

  1. 一步步分析Java深拷贝的两种方式-clone和序列化

    今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...

  2. java笔记线程两种方式模拟电影院卖票

    public class SellTicketDemo { public static void main(String[] args) { // 创建三个线程对象 SellTicket st1 = ...

  3. 创建Java多线程的两种方式和线程异常

    一.使用多线程的两种方法  使用多线程的两种方法有:继承Thread类和实现runable接口. 二.继承Thread类 来看一下thread类的源代码: class Thread implement ...

  4. Java异常处理的两种方式以及自定义异常的使用方法

    异常 就是程序出现了不正常的情况 Error:严重问题,不需要处理 Exception:称为异常类,他表示程序本身可以处理的问题 RuntimeException:在编译期是不检查的,出现问题后,需要 ...

  5. Java 和 数据库两种方式进行加锁

    java方式: publicstatic synchronized int generate(StringtableName){ Stringsql = "select value from ...

  6. python进程开启的两种方式

    一.进程 1.1.方式一 from multiprocessing import Process import time #方式一 def task(name): print(f"my na ...

  7. java判断数据类型两种方式

    instanceof        String s = ""; System.out.println(s instanceof String); // true     simp ...

  8. Java多线程的两种实现方式

    Java总共有两种方式实现多线程 方式1:通过继承Thread类的方式 package com.day04; /** * 通过继承Thread类并复写run方法来是实现多线程 * * @author ...

  9. 阿里巴巴--java多线程的两种实现方式,以及二者的区别

    阿里巴巴面试的时候,昨天问了我java面试的时候实现java多线程的两种方式,以及二者的区别当时只回答了实现线程的两种方式,但是没有回答上二者的区别: java实现多线程有两种方式: 1.继承Thre ...

  10. 【java并发】传统线程技术中创建线程的两种方式

    传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...

随机推荐

  1. 01-【HAL库】STM32实现串口打印

    一.什么是串口 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输 ...

  2. PicGo图床配置github仓库上传typora图片

    (前提是已注册github并新建一个仓库作为你上传图片的位置) 首先在PicGo官网下载软件:https://picgo.github.io/PicGo-Doc/zh/ 打开typora,找到偏好设置 ...

  3. keycloak~在认证的action中自定义重定向地址

    场景与实现逻辑 我的登录接口,在输入账号密码成功后进行中间页 中间页可以通过添加Authenticator的实现类来写逻辑 authenticate方法是渲染页面的,action方法是提交表单后的逻辑 ...

  4. Spring内存马分析

    环境搭建 踩了很多坑....,不过还好最后还是成功了 IDEA直接新建javaEE项目,然后记得把index.jsp删了,不然DispatcherServlet会失效 导入依赖: <depend ...

  5. 微服务集成Spring Cloud Zipkin实现链路追踪并集成Dubbo

    1.什么是ZipKin Zipkin 是一个根据 Google 发表的论文" Dapper" 进行开源实现的分布式跟踪系统. Dapper是Google 公司内部的分布式追踪系统, ...

  6. js推送网页到扩展屏上

    需求: 电脑上有两个屏幕,想在主屏上的网页中点击一个按钮,副屏就可以显示需要推送过去的网页 实现方法: 本方法使用的是js来实现的,亲测可行,支持火狐,但是不支持谷歌 demo: 主屏网页:1.htm ...

  7. 实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking

    实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking 论文url https://arxiv.org/abs/2003.11753 论文简述: ...

  8. HarmonyOS应用事件打点开发指导

      简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志,难以识别其中的关键信息.因此,应用开发者需要一种数据打点机制,用来评估如访问数.日活.用户操作习惯以及影响用户使用的关键因素等关键 ...

  9. 第二十一篇:信号、缓存、中间件、Form操作

    一.CSRF 二.中间件 三.缓存 四.信号 五.Form操作

  10. 面向切面编程AOP[二](java @EnableAspectJAutoProxy 代码原理)

    前言 @EnableAspectJAutoProxy 是启动aop功能的意思,那么里面是什么呢? 正文 @Target({ElementType.TYPE}) @Retention(Retention ...