Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

在 Spring 中,@Async 注解用于将方法标记为异步执行的方法。当使用 @Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。

在您提供的代码示例中,a1() 和 a2() 方法都被标记为 @Async,意味着它们将以异步方式执行。这意味着当调用这些方法时,它们将会在单独的线程中执行,而不会等待方法执行完成。

如果不使用 @Async 注解,则方法将会以同步方式执行。也就是说,当调用这些方法时,程序将会阻塞在方法执行处,直到方法执行完成才会继续执行后续代码。

因此,加上 @Async 注解的方法能够实现并发执行,而不加 @Async 注解的方法则会按照顺序逐个执行。根据您的代码示例,加上 @Async 注解后,a1() 和 a2() 方法将会同时启动并发执行,而不会相互阻塞。

需要注意的是,使用 @Async 注解需要配置一个任务执行器(Task Executor)来处理异步方法的调用。如果在 Spring Boot 项目中使用 @EnableAsync 注解来启用异步支持,Spring 将会自动配置默认的任务执行器。如果未配置任务执行器,则异步方法将在调用线程中执行,而不会启动新的线程来执行。

手动配置任务执行器

配置任务执行器(Task Executor)

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.Executor;
import java.util.concurrent.ThreadPoolExecutor;@Configuration
@EnableAsync
public class AsyncConfig {// 配置任务执行器@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 设置核心线程数executor.setCorePoolSize(10);// 设置最大线程数executor.setMaxPoolSize(20);// 设置队列容量executor.setQueueCapacity(100);// 设置线程活跃时间(秒)executor.setKeepAliveSeconds(60);// 设置线程名称前缀executor.setThreadNamePrefix("Async-");// 设置拒绝策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 初始化线程池executor.initialize();return executor;}
}

设置核心线程数、设置最大线程数和设置队列容量是线程池中的一些重要参数。

  • 核心线程数(Core Thread Pool Size):指的是线程池中保持的线程数量。即使这些线程处于空闲状态,它们也会一直存在于线程池中,以备接收新的任务。当线程池中的线程数量小于核心线程数时,新的任务将会创建新的线程来执行。
  • 最大线程数(Maximum Pool Size):指的是线程池中允许的最大线程数量。当线程池中的线程数量达到核心线程数时,如果还有新的任务需要执行,线程池将会再创建新的线程,直到达到最大线程数为止。当线程池中的线程数量达到最大值且队列也已满时,则会拒绝执行新的任务。
  • 队列容量(Queue Capacity):指的是线程池中任务队列可以容纳的最大任务数量。当线程池中的线程数量达到核心线程数时,如果还有新的任务需要执行,线程池将会将这些任务添加到任务队列中。如果任务队列已满,则会根据线程池的策略来处理这些被拒绝的任务。

这些参数的设置应该根据应用程序的需求和系统的资源来确定。过小的核心线程数和队列容量可能导致任务长时间排队等待执行,而过大的最大线程数则可能会消耗过多的系统资源。

定时任务A1

@Component
@EnableScheduling
public class A1 {@Async("taskExecutor")@Scheduled(cron = "0 0/1 * * * ?")public void a1(){for (int i = 0; i < 1000; i++) {System.out.println("我是a1");}}
}

定时任务A2

@Component
@EnableScheduling
public class A2 {@Async("taskExecutor")@Scheduled(cron = "0 0/1 * * * ?")public void a2(){for (int i = 0; i < 1000; i++) {System.out.println("我是a2");}}
}

加了@Async输出结果大概如下

A1和A2多线程交替执行,并发

我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
我是a1
我是a2
...

不加@Async输出结果大概如下

先执行完A1才会去执行A2,按顺序执行,阻塞

我是a1
我是a1
我是a1
我是a1
我是a1
我是a2
我是a2
我是a2
我是a2
我是a2
...

当涉及到设置线程池的核心线程数、最大线程数和队列容量时,需要根据具体的应用场景和需求来确定。下面是一些示例:

场景一:Web 服务器请求处理
假设有一个 Web 服务器,需要处理大量的并发请求。在这种情况下,可以考虑以下设置:

  • 核心线程数:根据服务器的负载和处理能力,设置一个适当的核心线程数,例如设置为 CPU 核心数的两倍。
  • 最大线程数:根据服务器的资源和性能,设置一个合理的最大线程数,例如设置为 CPU 核心数的四倍。
  • 队列容量:如果服务器的处理能力超过了核心线程数和最大线程数,可以设置一个适当的队列容量,以便将超出处理能力的请求暂存到队列中,例如使用一个有界队列。

场景二:后台任务处理
假设有一个后台任务需要处理大量的耗时操作,比如文件处理、数据导入等。在这种情况下,可以考虑以下设置:

  • 核心线程数:根据系统的负载和任务的数量,设置一个适当的核心线程数,例如设置为固定值,如10个线程。
  • 最大线程数:根据系统的资源和性能,设置一个合理的最大线程数,例如设置为20个线程。
  • 队列容量:如果任务数量超过了核心线程数和最大线程数,可以设置一个适当的队列容量,以便将超出处理能力的任务暂存到队列中,例如使用一个无界队列。

需要根据具体的应用场景和系统要求来灵活调整这些参数。合理设置这些参数可以提高系统的性能和资源利用率,避免因为线程过多或过少导致的性能问题或资源浪费。

yml中配置线程池

也可以直接在.yml中配置线程池大小

在这里插入图片描述

spring:task:scheduling:# 线程池大小pool:size: 30# 线程名前缀thread-name-prefix: myTask-

定时任务A1

@Component
@EnableScheduling
@EnableAsync
public class A1 {@Async@Scheduled(cron = "0 0/1 * * * ?")public void a1(){for (int i = 0; i < 1000; i++) {System.out.println("我是a1");}}
}

定时任务A2

@Component
@EnableScheduling
@EnableAsync
public class A2 {@Async@Scheduled(cron = "0 0/1 * * * ?")public void a2(){for (int i = 0; i < 1000; i++) {System.out.println("我是a2");}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

纯html通过XMLHttpRequest访问java后端接口并将返回结果输出到控制台【建议收藏】

我们需要准备几个部分&#xff1a; 1、后端接口【servlettomcat】 2、前端页面代码 3、js发起请求部分 后端接口&#xff1a; WebServlet("/h1") public class HController extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpS…

记录一下Canal的错误,主要是top.javatool.canal.client.util下的StringConvertUtil引起的

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 由于数据库的一个localdatetime字段是空的&#xff0c; 然后修改数据库数据同步canal的时候报了这个错误&#xff1a; Caused by: java.lang.IllegalArgumentException: Can not set java.time.LocalD…

在 WinForms 应用中使用 FtpWebRequest 进行文件操作和数据显示

在 WinForms 应用中使用 FtpWebRequest 进行文件操作和数据显示 引言 在企业级应用或桌面程序中&#xff0c;经常需要从远程服务器获取数据&#xff0c;并在用户界面上展示这些数据。本文将通过一个实际案例&#xff0c;演示如何在 Windows Forms 应用程序中使用 FtpWebReques…

一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库

前言 今天给大家分享一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库&#xff1a;LiteDB。本篇文章主要是介绍LiteDB和在.NET中如何使用。 LiteDB介绍 LiteDB 是一个小巧、快速和轻量级的 .NET NoSQL 嵌入式数据库。 无服务器的 NoSQL 文档存储 简单的 API&#xff0c;类似…

MySQL篇—通过Clone插件进行远程克隆数据(第三篇,总共三篇)

在介绍 Clone 最终篇之前&#xff0c;我们先简要回顾一下前面所讲的内容。在第一篇中&#xff0c;我们探讨了 Clone 的用途、使用的前提条件、存在的限制&#xff0c;以及它的备份原理。Clone 是一种用于复制和备份数据的工具&#xff0c;它能够快速高效地创建数据的精确副本。…

Vue3简介以及项目创建

vue是什么? (同音view)是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 知识储备&#xff08;具有以下的基本知识&#xff09; HTML CSS …

pgzrun 生命游戏制作过程详解

背景资料 康威生命游戏(Game of Life)是剑桥大学约翰何顿康威设计的计算机程序。 美国趣味数学大师马丁加德纳(Martin Gardner&#xff0c;1914-2010&#xff09;通过《科学美国人》杂志&#xff0c;将康威的生命游戏介绍给学术界之外的广大渎者&#xff0c;一…

分享一款刚开源的音乐人声分离工具!无需联网!页面化操作!

前言 人声分离 是一项重要的音频处理技术&#xff0c;它可以将混合音频中的 人声和背景音乐 分离出来&#xff0c;为音频处理和后期制作提供了便利。 随着人声分离技术的发展&#xff0c;越来越多的开源工具被开发出来&#xff0c;为音频处理领域带来了新的发展机遇。小编之前…

Netty开篇——基础介绍与准备(一)

I/O篇 Netty的介绍 Netty 是由JBOSS提供的一个Java开源框架在Github上Netty 是一个异步的、基于事件驱动的网络应用框架&#xff0c;用以快速开发高性能、高可靠性的网络IO程序。Netty 主要针对在TCP协议下面向客户端的高并发应用&#xff0c;或者Peer-to-Peer/P2P场景下的大量…

PPT插件-大珩助手-修改素材名称及搜索功能演示

修改素材名称及搜索功能演示 大珩助手的素材库&#xff0c;支持修改素材的名称&#xff0c;支持动态查找素材&#xff0c;删除素材 移动素材到其他分类 软件介绍 PPT大珩助手是一款全新设计的Office PPT插件&#xff0c;它是一款功能强大且实用的PPT辅助工具&#xff0c;支持…

天津大数据分析培训班 常见的大数据培训课程

大数据现在属于热门职业技能之一&#xff0c;不管是大学毕业生&#xff0c;计算机和数据相关专业青年&#xff0c;已经工作一阵的开发人员&#xff0c;运营小白&#xff0c;还是其他想进入这个行当的&#xff0c;可能还没有编程基础的转行人&#xff0c;都想尝试大数据行业&…

“三指针法“合并两个有序数组(力扣每日一练)

我的第一想法确实是&#xff1a;先合并数组&#xff0c;再排序&#xff0c;搞完。 哈哈哈&#xff0c;想那么多干嘛&#xff0c;目的达成了就好了。 力扣官方题解是双指针&#xff1a; 还有糕手&#xff1a; Python&#xff1a; def merge(nums1, m, nums2, n):# 两个指针分别…