二、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. 2022北航软件研究生入学考试991考试大纲-数据结构与C

    991"数据结构与C语言程序设计"考试大纲 "数据结构与C语言程序设计"考试内容包括"数据结构"与"C语言程序设计"两门 ...

  2. Women forum两周年有感

    今天是个高兴的日子,Women forum两周年庆. 当Nicole上台分享了她当妈妈的经历时,我感动得要哭了,导致轮到我上台演讲的时候,还沉浸在那种情绪中,导致我脱稿演讲了,于是我就超时了,实在是抱 ...

  3. Unity实现敌人生命条

    在敌人物体身上添加 Slider,将Background设置为黑色,FIllarea设置为绿色,调整滑块大小. 生命值减少代码设计如下: using System.Collections; using ...

  4. 使用Go语言开发一个短链接服务:二、架构设计

    章节  使用Go语言开发一个短链接服务:一.基本原理  使用Go语言开发一个短链接服务:二.架构设计  使用Go语言开发一个短链接服务:三.项目目录结构设计  使用Go语言开发一个短链接服务:四.生成 ...

  5. JSON格式化 动态生成表格 表格转置 行列转换 Excel导出

    先看效果 初始化: JSON格式化 : 生成表格-方式1 : 生成表格-方式2 : Excel导出 需要行求和.列求和功能的查看 JSON格式化 动态生成表格 表格转置 行列转换 Excel导出 行求 ...

  6. archlinux运行appimage

    1.cd进入appimage所在的目录 cd your_folder 2.赋予appimage运行权限 chmod +x your_file.appimage 3.运行appimage格式文件 ./y ...

  7. #高精度,卡特兰数#洛谷 2532 [AHOI2012]树屋阶梯

    题目 分析 设\(dp[n]\)表示大小为\(n\)的树屋阶梯方案数,如何不算重也不算漏 考虑在左下角填充一个尽量大的矩形,一共有\(n\)种方法, 然后剩下的两头就可以用前面的结果表示 也就是\(d ...

  8. #根号分治,背包#51nod 1597 有限背包计数问题 LOJ 6089 小Y的背包计数问题

    题目 有一个大小为\(n\)的背包,有\(n\)种物品, 第\(i\)种物品的大小为\(i\),且有\(i\)个, 求装满这个背包的方案数 \(n\leq 10^5\) 分析 直接多重背包会有问题,考 ...

  9. JDK10的新特性:var泛型和多个接口实现

    目录 简介 实现多个接口 使用多个接口 使用var 总结 简介 在JDK10的新特性:本地变量类型var中我们讲到了为什么使用var和怎么使用var. 今天我们来深入的考虑一下var和泛型,多个接口实 ...

  10. Pyside2简单案例

    代码: from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit app = QAppl ...