【SpringBoot】20 同步调用、异步调用、异步回调

Git仓库

https://gitee.com/Lin_DH/system

介绍

同步调用:指程序在执行时,调用方需要等待函数调用返回结果后,才能继续执行下一步操作,是一种阻塞式调用。
异步调用:指程序在执行时,调用方在调用函数后立即返回,不需要等待函数调用返回结果,可以直接执行下一步操作,当函数执行完成后,会通过回调或其他方式通知调用方,得到返回结果。
回调:在调用一个函数后,需要在函数执行中或执行后,将执行结果或状态返回给调用者。

代码实现

第一步:启动类上添加 @EnableAsync 注解,开启异步功能。

@EnableAsync
@SpringBootApplication
public class SystemApplication extends SpringBootServletInitializer {}

同步调用

第二步:添加同步调用业务逻辑
注:@Async 注解不能修饰的 static 修饰的函数,该类型的函数异步调用不会生效。

package com.lm.system.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Random;

/**
 * 同步调用
 * @author DUHAOLIN
 * @date 2024/10/17
 */
@Slf4j
@Component
public class SyncTask {

    public static Random random = new Random();

    public void one() throws InterruptedException {
        commonTask("一");
    }
    


    public void two() throws InterruptedException {
        commonTask("二");
    }

    public void three() throws InterruptedException {
        commonTask("三");
    }

    public void commonTask(String s) throws InterruptedException {
        log.info("开始执行任务" + s);
        long startTime = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long endTime = System.currentTimeMillis();
        log.info("完成任务" + s + ",耗时:" + (endTime - startTime) + "毫秒");
    }

}

第三步:测试类添加同步调用的测试方法

SystemApplicationTests.java

@Slf4j
@SpringBootTest(classes = SystemApplication.class)
class SystemApplicationTests {
    
    @Resource
    private SyncTask syncTask;

    @Test
    public void syncTest() throws InterruptedException {
        long startTime = System.currentTimeMillis();
        syncTask.one();
        syncTask.two();
        syncTask.three();
        long endTime = System.currentTimeMillis();
        log.info("任务总耗时:" + (endTime - startTime) + "毫秒");
    }
    
}

异步调用

第四步:添加异步调用业务逻辑

AsyncTask.java

/**
 * 异步调用
 * @author DUHAOLIN
 * @date 2024/10/17
 */
@Slf4j
@Component
public class AsyncTask {

    public static Random random = new Random();

    @Async
    public void one() throws InterruptedException {
        commonTask("一");
    }

    @Async
    public void two() throws InterruptedException {
        commonTask("二");
    }

    @Async
    public void three() throws InterruptedException {
        commonTask("三");
    }

    public void commonTask(String s) throws InterruptedException {
        log.info("开始执行任务" + s);
        long startTime = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long endTime = System.currentTimeMillis();
        log.info("完成任务" + s + ",耗时:" + (endTime - startTime) + "毫秒");
    }

}

第五步:测试类添加异步调用的测试方法

SystemApplicationTests.java

@Resource
private AsyncTask asyncTask;

@Test
public void asyncTest() throws InterruptedException {
    long startTime = System.currentTimeMillis();
    asyncTask.one();
    asyncTask.two();
    asyncTask.three();
    long endTime = System.currentTimeMillis();
    log.info("任务总耗时:" + (endTime - startTime) + "毫秒");
}

异步回调(常用)

第六步:添加异步回调业务逻辑

AsyncCallBackTask.java

package com.lm.system.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Random;

package com.lm.system.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.CompletableFuture;

/**
 * 异步回调
 * @author DUHAOLIN
 * @date 2024/10/17
 */
@Slf4j
@Component
public class AsyncCallBackTask {

    public static Random random = new Random();

    @Async
    public CompletableFuture<String> one() throws InterruptedException {
        log.info("开始执行任务一");
        long startTime = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long endTime = System.currentTimeMillis();
        log.info("完成任务一,耗时:" + (endTime - startTime) + "毫秒");
        return CompletableFuture.completedFuture("任务一执行完成");
    }

    @Async
    public CompletableFuture<String> two() throws InterruptedException {
        log.info("开始执行任务二");
        long startTime = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long endTime = System.currentTimeMillis();
        log.info("完成任务二,耗时:" + (endTime - startTime) + "毫秒");
        return CompletableFuture.completedFuture("任务二执行完成");
    }

    @Async
    public CompletableFuture<String> three() throws InterruptedException {
        log.info("开始执行任务三");
        long startTime = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long endTime = System.currentTimeMillis();
        log.info("完成任务三,耗时:" + (endTime - startTime) + "毫秒");
        return CompletableFuture.completedFuture("任务三执行完成");
    }

}

第七步:测试类添加异步回调的测试方法

SystemApplicationTests.java

@Resource
    private AsyncCallBackTask asyncCallBackTask;

    @Test
    public void asyncCallBackTaskTest() throws InterruptedException {
        long startTime = System.currentTimeMillis();
        CompletableFuture<String> one = asyncCallBackTask.one();
        CompletableFuture<String> two = asyncCallBackTask.two();
        CompletableFuture<String> three = asyncCallBackTask.three();
        CompletableFuture.allOf(one, two, three).join();
        long endTime = System.currentTimeMillis();
        log.info("任务总耗时:" + (endTime - startTime) + "毫秒");
    }

效果图

同步调用
在这里插入图片描述
异步调用
执行完异步调用,只有任务的部分相关输出,任务的执行顺序也是乱序的。
在这里插入图片描述
异步回调
在这里插入图片描述

异步任务线程池配置

介绍

当我们用异步调用或异步回调进行并发操作时,加速了任务的执行效率,但是如果只是直接简单的创建来使用,可能会碰到一些问题和风险。当接口被频繁调用,异步任务创建的数量达到一定量级,可能会导致内存溢出,此时我们就需要对创建异步任务的操作,加上线程池的相关配置。
在这里插入图片描述
queueCapacity:缓冲队列的容量,默认为INT的最大值(2的31次方-1)
maxSize:允许的最大线程数,默认为INT的最大值(2的31次方-1)

具体配置

在这里插入图片描述

application.yml

spring:
  task:
    execution:
      pool:
        core-size: 2 #线程池创建时的初始化线程数,默认为8
        max-size: 5 #线程池的最大线程数,默认为int最大值
        queue-capacity: 10 #用来缓冲执行任务的队列,默认为int最大值
        keep-alive: 60s #线程终止前允许保持空闲的时间,默认为60s
        allow-core-thread-timeout: true #是否允许核心线程超时
      shutdown:
        await-termination: false #是否等待剩余任务完成后才关闭应用
        await-termination-period: #等待剩余任务完成的最大时间
      thread-name-prefix: task- #线程名的前缀,设置好了之后可以方便我们在日志中查看处理任务所在的线程池

application.Properties

spring.task.execution.pool.core-size=2
spring.task.execution.pool.max-size=5
spring.task.execution.pool.queue-capacity=10
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.allow-core-thread-timeout=true
spring.task.execution.shutdown.await-termination=false
spring.task.execution.shutdown.await-termination-period=
spring.task.execution.thread-name-prefix=task-

效果图

再次执行异步回调方法,得到如下效果图。
当前配置的初始化线程数为2,最大线程数为5,缓存队列为10,只有当缓存队列满且当前线程数小于最大线程数时,才会申请新的线程来执行任务(如:缓存队列为11,初始化线程数为2,最大线程数为5)。
在这里插入图片描述

项目结构图

在这里插入图片描述

参考资料

Spring Boot 2.x基础教程:使用@Async实现异步调用【https://www.didispace.com/spring-boot-2/8-3-async-1.html】
Spring Boot 2.x基础教程:配置@Async异步任务的线程池【https://www.didispace.com/spring-boot-2/8-3-async-2.html】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/915703.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Elasticsearch入门到落地】1、初识Elasticsearch

一、什么是Elasticsearch Elasticsearch&#xff08;简称ES&#xff09;是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。它使用Java编写&#xff0c;基于Apache Lucene来构建索引和提供搜索功能&#xff0c;是一个分布式、可扩展、近实…

开源项目低代码表单设计器FcDesigner扩展自定义的容器组件.例如col

开源项目低代码表单设计器FcDesigner中的容器组件可以帮助您实现更灵活的布局设计。在这里&#xff0c;我们以一个简单的 Col 容器组件为例&#xff0c;来演示如何定义和使用它。 源码地址: Github | Gitee | 文档 定义组件 首先&#xff0c;我们创建一个 Col 组件&#xf…

【mysql】使用宝塔面板在云服务器上安装MySQL数据库并实现远程连接

前言 使用宝塔Linux面板安装MySQL数据库并实现远程连接 使用宝塔面板安装mysql 宝塔面板&#xff0c;华为云开放3306端口 一些命令 // 命令行连接数据库 mysql -uroot -p // MySQL 5 版本 GRANT ALL ON *.* TO root% IDENTIFIED BY 替换成你的root密码 WITH GRANT OPTION; // …

【算法一周目】双指针(2)

目录 有效三角形的个数 解题思路 C代码实现 和为s的两个数字 解题思路 C代码实现 三数之和 解题思路 C代码实现 四数之和 解题思路 C代码实现 有效三角形的个数 题目链接&#xff1a;611. 有效三角形的个数题目描述&#xff1a;给定一个包含非负整数的数组nums&…

Nginx+ThinkPHP+Vue解决跨域问题的方法详解

解决过程主要有两个步骤。 1.nginx配置允许跨域 在你部署的网站对应的端口配置文件里设置&#xff0c;我的目录结构是这样的&#xff1a; server { listen 8080; server_name localhost; root "D:/phpstudy_pro/WWW/admin/landpage_se…

实用教程:如何无损修改MP4视频时长

如何在UltraEdit中搜索MP4文件中的“mvhd”关键字 引言 在视频编辑和分析领域&#xff0c;有时我们需要深入到视频文件的底层结构中去。UltraEdit&#xff08;UE&#xff09;和UEStudio作为强大的文本编辑器&#xff0c;允许我们以十六进制模式打开和搜索MP4文件。本文将指导…

wordpress搭建主题可配置json

网站首页展示 在线访问链接 http://dahua.bloggo.chat/ 配置json文件 我使用的是argon主题&#xff0c;你需要先安装好主题&#xff0c;然后可以导入我的json文件一键配置。 需要json界面配置文件的&#xff0c;可以在评论区回复&#xff0c;看见评论我会私发给你。~

C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型

用自己定义的数据结构作为rtree的key。 // rTree的key struct OverlapKey {using BDPoint boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian>; //双精度的点using MyRTree boost::geometry::index::rtree<OverlapKey, boost::geometry::in…

微信小程序-prettier 格式化

一.安装prettier插件 二.配置开发者工具的设置 配置如下代码在setting.json里&#xff1a; "editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml"…

【机器学习】数学知识:标准差,方差,协方差,平均数,中位数,众数

标准差、方差和协方差是统计学中重要的概念&#xff0c;用于描述数据的分散程度和变量之间的关系。以下是它们的定义和公式&#xff1a; 1. 标准差 (Standard Deviation) 标准差是方差的平方根&#xff0c;表示数据的分散程度&#xff0c;以与数据相同的单位表示。 公式&…

Redis8:商户查询缓存2

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

【QT常用技术讲解】优化网络链接不上导致qt、qml界面卡顿的问题

前言 qt、qml项目经常会涉及访问MySQL数据库、网络服务器&#xff0c;并且界面打开时的初始化过程就会涉及到链接Mysql、网络服务器获取数据&#xff0c;如果网络不通&#xff0c;卡个几十秒&#xff0c;会让用户觉得非常的不爽&#xff0c;本文从技术调研的角度讲解解决此类问…

HelloMeme 上手即用教程

HelloMeme是一个集成空间编织注意力的扩散模型&#xff0c;用于生成高保真图像和视频。它提供了一个代码库&#xff0c;包含实验代码和预训练模型&#xff0c;支持PyTorch和FFmpeg。用户可以通过简单的命令行操作来生成图像和视频。 本文将详细介绍&#xff0c;如何在GPU算力租…

公开一下我的「个人学习视频」!

哈喽&#xff0c;大家好&#xff0c;我是六哥。 鉴于上次分享&#xff0c;很多同学说&#xff0c;六哥能整一些百度网盘的资源吗&#xff1f; 可以&#xff0c;来安排&#xff0c;看看有你心动的吗&#xff1f; 性能测试系列 测开系列 python方向 Java方向 主管必会系列 质…

13.观察者模式设计思想

13.观察者模式设计思想 目录介绍 01.观察者模式基础 1.1 观察者模式由来1.2 观察者模式定义1.3 观察者模式场景1.4 观察者模式思考 02.观察者模式实现 2.1 罗列一个场景2.2 用例子理解观察者2.3 案例演变分析2.4 观察者模式基本实现 03.观察者模式分析 3.1 观察者模式案例3.2…

webpack指南

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;webpack篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南 概念 中文&#xff1a; webpack | webpack中文文档 | webpack中文网 英文&…

CSS高级技巧_精灵图_字体图标_CSS三角_vertical-align(图像和文字居中在同一行)_溢出文字省略号显示

目录 CSS高级技巧 1. 精灵图 1.1 为什么需要精灵图 1.2 精灵图&#xff08;sprites&#xff09;的使用 1.2 精灵图的使用 案例&#xff1a;拼出自己名字 2. 字体图标 2.1 字体图标的产生 2.2 字体图标的优点 2.3 字体图标的下载 2.4 字体图标的引入 2.4.1 字体文件格…

仪表板展示|DataEase看中国:历年双十一电商销售数据分析

背景介绍 2024年“双十一”购物季正在火热进行中。自2009年首次推出至今&#xff0c;“双十一”已经成为中国乃至全球最大的购物狂欢节&#xff0c;并且延伸到了全球范围内的电子商务平台。随着人们消费水平的提升以及电子商务的普及&#xff0c;线上销售模式也逐渐呈现多元化…

若依项目-结构解读

项目结构 admin模块 common模块 framework模块 service模块 配置 依赖关系 前端接口 src 表结构

RTSP前端实时流

因项目需求探索前端实时流&#xff0c;本文介绍了 RTSP 前端不能直接播放&#xff0c;需中间层转换协议&#xff0c;如 RTSP 转 RTMP、HLS、HTTP-FLV&#xff0c;分别阐述其特点、配置和播放方式&#xff0c;还提及关键帧、延迟与卡顿的关系&#xff0c;以及直播平台使用云服务…