【多线程开发 6】spring中的注解/API的线程问题

news2024/12/26 12:04:11

【多线程开发 6】spring中的注解/API的线程问题

2024年8月14日

文章目录

  • 【多线程开发 6】spring中的注解/API的线程问题
    • 1 Future和CompletableFuture
    • 2 hutool的异步任务
    • 3 @Async
    • 4 @Schedule
    • 5 stream Parallel
    • 6 ForkJoinPool
    • 7 @Transactional

除了Java自带默认线程池,基于Java的spring框架也有很多自带的默认线程池,有时候我们的一些需要线程池的操作可能通过提供的api和注解隐藏掉了,不熟悉的话会出现线程相关的问题

1 Future和CompletableFuture

Future和CompletableFuture都是Java提供的用来执行异步方法的情况。其中,Future只能包装一个异步任务,最后还是要把这个任务提交给特定线程池。

CompletableFuture则会使用默认线程池,但是比较复杂:

  • 无JVM参数前提下:

    若服务器的核心数小于等于2,commonParallelism 则为1,即useCommonPool 为false,new 一个线程池ThreadPerTaskExecutor 。

    若服务器的核心数大于2,commonParallelism 则为 核心数 - 1,即useCommonPool 为true,使用ForkJoinPool线程池。

  • 有JVM参数情况下:

    以设置参数为准。大于1小于等于32767。和上面判断一致

以上CompletableFuture的总结来自 这篇文章 从用法到源码再到应用场景:全方位了解CompletableFuture及其线程池 有兴趣深挖一下的可以看下

综上我们推荐使用CompletableFuture时候也需要主动指定线程池,没有指定线程池的情况下,CompletableFuture要么使用ForkJoinPool,要么不使用线程池,ForkJoinPool做CPU密集型任务好用,我们有时候做IO密集型任务则不需要他,需要指定IO型线程池。

2 hutool的异步任务

hutool在提交任务的时候,会自动提交到一个默认的ExecutorService对象中,这个对象会使用如下的类的builder(0方法,这个对象的参数如下

一些小项目直接使用OK的,但是如果大项目使用的话,风险会较大,他的最大线程数是最大值,任务队列也是1024,不一定满足业务需要,核心线程数是0

在这里插入图片描述

3 @Async

springboot 2.1.0 之前:simpleasynctaskexecutor,这个线程池会是不安全的线程池,很容易出现OOM,因为他创建新线程、无限、不重用

springboot 2.1.0 之后:taskexecutor这个是springboot的一个自带bean,类型是TaskExecutor,一般是有的,如果没有才会找simpleasynctaskexecutor

4 @Schedule

在Spring Boot中,@Scheduled注解是基f于Java的ThreadPoolExecutor和ScheduledThreadPoolExecutor实现的。当我们配置了一个定时任务后,Spring Boot会首先创建一个ScheduledThreadPoolExecutor线程池,并将定时任务添加到该线程池中等待执行。然后,在指定的时间到来之后,线程池会为该定时任务分配一个线程来执行。如果该定时任务还未执行完毕,在下一个周期到达时,线程池会为该任务再次分配一个线程来执行。通过这种方式,@Scheduled可以非常方便地实现周期性的定时任务f于Java的ThreadPoolExecutor和ScheduledThreadPoolExecutor实现的。

当然schedule注解可以指定线程池,需要实现SchedulingConfigurer 方法

    @Configuration
    @DependOn("executor")
    public class ScheduleConfig implements SchedulingConfigurer {
        @Resource
        private ThreadPoolExecutor executor;
        
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            //具体逻辑需要自己写
            ThreadPoolTaskScheduler threadPoolTaskScheduler = executor;
        }
    }
    

或者可以再schedule注解上再加一个 @Async注解,做到异步线程中去做。

5 stream Parallel

parallelStream不能使用自定义线程池,默认情况下,Stream使用的是ForkJoinPool.commonPool(),这是一个公用的线程池,被整个程序所使用。

但是stream parallel本身就符合ForkJoinPool的Fork/Join思想,一般不会去进行修改。但是如果有需要,我们可以单独给并行流创建一个线程池供他们使用。

如创建一个并行度为4的ForkJoinPool,通过给该ForkJoinPool提交lambda表达式任务来解决这个问题

6 ForkJoinPool

详情可以参照该文章 线程池ForkJoinPool简介

7 @Transactional

使用该注解时不能做和多线程/异步线程相关的事情,否则事务容易失效,详情请见 注解@Transactional 原理和常见的坑

引用文章:

  • Spring中异步注解@Async的使用、原理及使用时可能导致的问题
  • Async注解不指定线程池?默认用的又是什么?
  • hutool官网
  • 从用法到源码再到应用场景:全方位了解CompletableFuture及其线程池
  • SpringBoot定时任务@Scheduled的多线程使用
  • 注解@Transactional 原理和常见的坑
  • 线程池ForkJoinPool简介
  • 多线程场景下谨慎使用@Transactional注解,你不信我也没办法
  • https://blog.csdn.net/qq_33709582/article/details/132686293)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac本地搭建docker+k8s步骤

概览: * kubectl安装 * minikube安装 * dashboard安装 主机配置: * mac M2 (arm架构) 服务及版本概览: 服务名称版本 kubectl v1.29.2 Kubernetes v1.30.0 kicbase v0.0.44 dashboard v2.7.0 docker 26.…

Linux:进程概念

文章目录 进程概念1、冯诺依曼体系结构2、进程2.1基本概念2.2描述进程-PCB2.3组织进程2.4查看进程2.5通过系统调用获取进程标识符2.6通过系统调用创建进程-fork初识 进程概念 1、冯诺依曼体系结构 目前我们认识的计算机中,都是由一个个硬件构成 输入单元&#xff1…

c语言基础-------指针变量作为函数参数

指针变量作为函数参数 在 C 语言中,指针变量作为函数参数是一种常见的做法,它允许函数修改通过指针传递的变量。这是通过指针的地址传递实现的,而不是通过值传递。 指针作为函数参数的优点 修改原始数据:当函数接受一个指针作…

经典游戏,用java实现的坦克大战小游戏

今天给大家分享一个使用java编写的坦克大战小游戏,整体还是挺好玩的,通过对这款游戏的简单实现,加深对java基础的深刻理解。 一、设计思路 1.坦克大战小游戏通过java实现,其第一步需要先绘制每一关对应的地图,地图包括…

机器学习(5)--正则化之L1和L2正则化

文章目录 正则化一、正则化的基本原理二、L1正则化(Lasso)三、L2正则化(Ridge)四、L1与L2正则化的比较 总结 正则化 正则化是一种在机器学习和深度学习中常用的技术手段,旨在提高模型的泛化能力,减少过拟合…

深入探讨C语言中的高级指针操作

目录 指针与内存管理的高级技巧 1. 动态数组的重新分配 2. 内存碎片化的处理 3. 内存对齐 函数指针数组与回调函数的高级用法 1. 基本函数指针用法 2. 函数指针数组 3. 回调函数的使用 指针与数据结构的结合 1. 自定义链表 C语言以其强大的底层操作能力和高效的性能著…

【信创】Linux下EFI引导配置工具efibootmgr _ 统信 _ 麒麟 _ 方德

往期好文:deepin V23 Release 安装与功能介绍!!! Hello,大家好啊!今天给大家带来一篇关于在信创操作系统上使用EFI引导管理器配置工具efibootmgr命令详解的文章。efibootmgr是一个在基于UEFI的系统中管理EF…

AI数字员工技能全开,招生、培训、写教案,样样都行

只需要几个AI数字员工,就可以协助您办一所高质量的学校。 教务管理、教师培训、招生咨询、家校沟通、学生评价、资料整理、学习伴侣、写教案、总结、学生评语等。 这些都可以用AI数字员工来完成。 比如,AI培训专员给教师做制度培训、教学培训&#xf…

裴蜀定理相关结论

裴蜀定理: axbygcd(a,b) 必定有解 1. 有无限个数凑不出来 有无限个数凑不出来 2. 最大凑不出的数字 在 的条件下,最大凑不出的数为 推广:若数字数目大于2,gcd仍然为1,最大凑不出来的数字一定小于上面的结论值,即局…

计算机网络——TCP协议与UDP协议详解(上)

一、前言 1.1 再次理解传输层 传输层是计算机网络中的一层,位于网络层和应用层之间。它主要负责在网络中的两个端系统之间提供可靠的、端到端的数据传输服务。简单理解,传输层就是负责在源主机和目标主机之间提供端到端的数据传输。 传输层的两个主要协…

EasyRecovery 16/17数据恢复软件2024最新永久破解版激活码注册码分享

EasyRecovery (易恢复中国)是由全球著名数据厂商Ontrack 出品的一款数据文件恢复软件。支持恢复不同存储介质数据:硬盘、光盘、U盘/移动硬盘、数码相机、Raid文件恢复等,能恢复包括文档、表格、图片、音视频等各种文件。 开发背…

鸿蒙开发5.0【基于ArkUI的验证码】实现

场景描述 场景一:基于自定义键盘的验证码实现,进入页面后直接输入验证码,第一个验证码输入完后可自动跳到下一个,拉起的键盘是自定义数字键盘,验证码的输入框带选中效果。 场景二:基于系统键盘的验证码实…

顶顶通呼叫中心中间件-一句话识别语音识别安装步骤

顶顶通呼叫中心中间件-一句话模型安装步骤,对接mod_vad。一句话识别(http接口提交录音文件识别) 一、安装一句话模型 一句话识别(http接口提交录音文件识别),比如对接mod_vad(老电话机器人接口) curl -s…

C#中的多线程案例

使用Task写一个进度条 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.For…

【有手就行】:从无到有在win10上用docker搭建svn服务器

前言 之所以要搭建svn服务器,是因为在用docker打包项目时方便,如果没有svn就需要手动拷贝项目到容器内,用svn直接update就可以轻松拿到最新代码,岂不快哉 准备工作 1、先安装docker,请移步 docker安装 2、选择svn-s…

【每日力扣中医养生】力扣2608. 图中的最短环

2608. 图中的最短环 文章目录 【每日力扣&中医养生】力扣2608. 图中的最短环题目描述示例示例 1示例 2 输入输出说明解题思路Python代码复杂度分析总结 【每日力扣&中医养生】力扣2608. 图中的最短环 《黄帝内经》阴阳应象大论篇第五,提到“秋伤于湿&…

Leetcode 209,713,3 滑动窗口 C++实现

Leetcode 209. 长度最小的子数组 问题:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组&#xff0c…

redis 遍渐进式历

1.scan cursor [match pattern] [coutn] [type]:以渐进式的方式进行建的遍历 cursor:是光标 指向当前遍历的位置 设置成0表示当前从0开始获取 math parttern :和keys命令一样的 keys * count: 限制一次遍历能够获取到多少个 元素默认是10 type :这次遍历只想获取…

数据库原理--关系模型简述

目录 一、关系模型研究什么 二、关系模型的三要素 三、关系模型与关系数据库语言的关系 一、关系模型研究什么 一个关系(relation)就是一个表(Table),关系模型就是处理Table的,它由三个部分组成: 描述DB各种数据的基本结构(Table/Relation)描述Table与Table之间…

Docker安装Redis集群记录

redis集群整体的安装效果 备注:本机docker容器的宿主机ip为192.168.0.200,下面的配置全部基于当前IP进行配置; 1 docker镜像下载使用的国内地址 vi /etc/docker/daemon.json{"registry-mirrors": ["https://ustc-edu-cn.mir…