iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Springboot线程池并发处理数据优化方式
  • 178
分享到

Springboot线程池并发处理数据优化方式

2024-04-02 19:04:59 178人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录第一步:首先配置线程基本参数第二步:让Spring Boot加载第三步:创建一个service接口第四步:编写现实类第五步:测试结果如下第一步:首先配置线程基本参数 可以放在ap

第一步:首先配置线程基本参数

可以放在application.propertes文件种也可以放在自己新建的config/文件目录下,注意:但是需要使用@PropertySource把配置文件进行加载。


# 异步线程配置
# 配置核心线程数
async.executor.thread.core_pool_size = 8
# 配置最大线程数
async.executor.thread.max_pool_size = 20
# 配置队列大小
async.executor.thread.queue_capacity = 99999
# 配置线程池中的线程的名称前缀
async.executor.thread.name.prefix = async-service-

第二步:让spring Boot加载

用来定义如何创建一个ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync这两个注解,表示这是个配置类,并且是线程池的配置类


@Slf4j
@EnableAsync
@Configuration
public class RCExecutorConfig {
 
  @Value("${async.executor.thread.core_pool_size}")
     private int corePoolSize;
     @Value("${async.executor.thread.max_pool_size}")
     private int maxPoolSize;
     @Value("${async.executor.thread.queue_capacity}")
     private int queueCapacity;
     @Value("${async.executor.thread.name.prefix}")
     private String namePrefix;
    
     @Bean(name = "asyncServiceExecutor")
     public Executor asyncServiceExecutor() {
         log.info("start asyncServiceExecutor");
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         //ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
         //配置核心线程数
         executor.setCorePoolSize(corePoolSize);
         //配置最大线程数
         executor.setMaxPoolSize(maxPoolSize);
         //配置队列大小
         executor.setQueueCapacity(queueCapacity);
         //配置线程池中的线程的名称前缀
         executor.setThreadNamePrefix(namePrefix);
 
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务
         // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
         //执行初始化
         executor.initialize();
         return executor;
     }
}

第三步:创建一个service接口

是异步线程的接口,便于测试


public interface AsyncService {
 
 
    void executeAsync();
}

第四步:编写现实类

将Service层的服务异步化,在executeAsync()方法上增加注解@Async("asyncServiceExecutor"),asyncServiceExecutor方法是前面RCExecutorConfig.java中的方法名,表明executeAsync方法进入的线程池是asyncServiceExecutor方法创建的。

测试方面这里我加入了一个定时任务,使用的是corn表达式。(不懂得同学可以网上了解一下)


@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
 
 @Override
 @Scheduled(cron = " */1 * * * * ? ")
 @Async("asyncServiceExecutor")
 public void executeAsync() {
  log.info("start executeAsync");
        System.out.println("异步线程执行批量插入等耗时任务");
        log.info("end executeAsync");  
 }  
}

第五步:测试结果如下

10:32:15.004 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:15.004 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:16.003 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:16.004 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:17.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:17.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:18.002 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:18.003 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:19.002 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:19.003 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:20.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:20.002 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:21.002 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:21.002 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:22.004 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:22.005 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:23.001 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:23.003 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:24.003 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:24.003 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:25.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:25.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:26.002 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:26.002 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:27.002 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:27.003 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:28.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:28.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:29.001 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:29.002 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:30.001 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:30.001 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:32:31.001 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:32:31.001 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync

还没完:

通过以上日志可以发现,[async-service-]是有多个线程的,显然已经在我们配置的线程池中执行了,表明每次请求都快速响应了,而耗时的操作都留给线程池中的线程去异步执行;

还有另一个问提就是,虽然已经用上了线程池,但是依然不清楚线程池当时的情况,有多少线程在执行,多少在队列中等待呢?于是这里我创建了一个ThreadPoolTaskExecutor的子类,可以把每次提交线程的时候都会将当前线程池的运行状况打印出来


import lombok.extern.slf4j.Slf4j;
 
@Slf4j
public class VisiableThreadPoolTaskExecutor extends  ThreadPoolTaskExecutor {
 
    
 private static final long serialVersionUID = -3518460523928455463L; 
 private void showThreadPoolInfo(String prefix) {
        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor(); 
        if (null == threadPoolExecutor) {
            return;
        }
 
        log.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
                this.getThreadNamePrefix(),
                prefix,
                threadPoolExecutor.getTaskCount(),
                threadPoolExecutor.getCompletedTaskCount(),
                threadPoolExecutor.getActiveCount(),
                threadPoolExecutor.getQueue().size());
    }
 
    @Override
    public void execute(Runnable task) {
        showThreadPoolInfo("1. do execute");
        super.execute(task);
    }
 
    @Override
    public void execute(Runnable task, long startTimeout) {
        showThreadPoolInfo("2. do execute");
        super.execute(task, startTimeout);
    }
 
    @Override
    public Future<?> submit(Runnable task) {
        showThreadPoolInfo("1. do submit");
        return super.submit(task);
    }
 
    @Override
    public <T> Future<T> submit(Callable<T> task) {
        showThreadPoolInfo("2. do submit");
        return super.submit(task);
    }
 
    @Override
    public ListenableFuture<?> submitListenable(Runnable task) {
        showThreadPoolInfo("1. do submitListenable");
        return super.submitListenable(task);
    }
 
    @Override
    public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
        showThreadPoolInfo("2. do submitListenable");
        return super.submitListenable(task);
    } 
}

其次:修改RCExecutorConfig.java的asyncServiceExecutor方法,

将ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor()改为ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor()


 @Bean(name = "asyncServiceExecutor")
     public Executor asyncServiceExecutor() {
         log.info("start asyncServiceExecutor");
         //ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
         //配置核心线程数
         executor.setCorePoolSize(corePoolSize);
         //配置最大线程数
         executor.setMaxPoolSize(maxPoolSize);
         //配置队列大小
         executor.setQueueCapacity(queueCapacity);
         //配置线程池中的线程的名称前缀
         executor.setThreadNamePrefix(namePrefix); 
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务
         // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
         //执行初始化
         executor.initialize();
         return executor;
     }

测试结果如下:

异步线程执行批量插入等耗时任务
10:41:35.003 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:36.001 [sheduled-pool-1-thread-1] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [5], completedTaskCount [5], activeCount [0], queueSize [0]
10:41:36.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:36.002 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:37.001 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [6], completedTaskCount [6], activeCount [0], queueSize [0]
10:41:37.001 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:37.002 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:38.002 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [7], completedTaskCount [7], activeCount [0], queueSize [0]
10:41:38.002 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:38.002 [async-service-8] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:39.001 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [8], completedTaskCount [8], activeCount [0], queueSize [0]
10:41:39.001 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:39.002 [async-service-1] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:40.003 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [9], completedTaskCount [9], activeCount [0], queueSize [0]
10:41:40.003 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:40.003 [async-service-2] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:41.001 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [10], completedTaskCount [10], activeCount [0], queueSize [0]
10:41:41.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:41.001 [async-service-3] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:42.000 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [11], completedTaskCount [11], activeCount [0], queueSize [0]
10:41:42.000 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:42.000 [async-service-4] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:43.001 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [12], completedTaskCount [12], activeCount [0], queueSize [0]
10:41:43.002 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:43.003 [async-service-5] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:44.001 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [13], completedTaskCount [13], activeCount [0], queueSize [0]
10:41:44.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync
异步线程执行批量插入等耗时任务
10:41:44.001 [async-service-6] INFO c.a.a.service.impl.AsyncServiceImpl - end executeAsync
10:41:45.000 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [14], completedTaskCount [14], activeCount [0], queueSize [0]
10:41:45.001 [async-service-7] INFO c.a.a.service.impl.AsyncServiceImpl - start executeAsync

解释:这里意思提交了14个任务,处理了14个任务,对列中还剩0个任务

10:41:45.000 [sheduled-pool-1-thread-7] INFO c.a.a.e.t.VisiableThreadPoolTaskExecutor - async-service-, 2. do submit,taskCount [14], completedTaskCount [14], activeCount [0], queueSize [0]

到此为止就OK了!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Springboot线程池并发处理数据优化方式

本文链接: https://www.lsjlt.com/news/161125.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Springboot线程池并发处理数据优化方式
    目录第一步:首先配置线程基本参数第二步:让Spring Boot加载第三步:创建一个service接口第四步:编写现实类第五步:测试结果如下第一步:首先配置线程基本参数 可以放在ap...
    99+
    2024-04-02
  • 如何优化Springboot线程池并发处理数据方式
    这篇文章给大家分享的是有关如何优化Springboot线程池并发处理数据方式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。第一步:首先配置线程基本参数可以放在application.propertes文件种也可以...
    99+
    2023-06-22
  • Java 线程池的艺术:优雅地管理并发
    线程池基础 线程池是一组预先创建并管理的线程,用于执行任务。它提供了以下主要好处: 资源优化:通过重用现有的线程,线程池消除了重复创建和销毁线程的开销,从而显着提高性能。 并发控制:通过限制同时执行的任务数量,线程池可以防止系统过载,确...
    99+
    2024-03-13
    线程池
  • java 多线程处理大量并发数据
    Java中多线程是一种处理数据的常见方式,它可以同时执行多个线程以提高程序的性能和效率。下面是一个使用多线程处理数据的示例代码: public class DataProcessor { pub...
    99+
    2023-09-07
    java 开发语言
  • springboot内置tomcat调优并发线程数解析
    目录前言参数线程池核心线程数线程池最大线程数请求最大连接数accept-counttomcat线程池处理机制总结前言 本文解析springboot内置tomcat调优并发线程数的一些...
    99+
    2024-04-02
  • android多线程并发处理的方式有哪些
    Android多线程并发处理的方式有以下几种:1. 使用Thread类:创建Thread对象,重写run()方法,在run()方法中...
    99+
    2023-09-23
    android
  • linux多线程并发的处理方式有哪些
    在Linux中,有多种方式可以实现多线程并发的处理:1. 使用线程库:Linux提供了一些线程库,如POSIX线程库(pthread...
    99+
    2023-09-27
    linux
  • mfc多线程并发处理的方式有哪些
    MFC(Microsoft Foundation Classes)是一个基于C++的应用程序框架,用于开发Windows操作系统上的...
    99+
    2024-02-29
    mfc
  • 掌握 Java 线程池,解锁并发处理的潜力
    在当今复杂的分布式系统中,并发处理对于高效执行任务至关重要。Java 线程池是一种强大的工具,它通过管理和调度线程,帮助开发人员充分利用并发性,从而提高性能和可伸缩性。 线程池概述 线程池是一个线程的集合,这些线程可以根据需要按需创建和销...
    99+
    2024-03-13
    线程池
  • Go语言中如何处理并发数据库连接的连接池优化问题?
    Go语言中如何处理并发数据库连接的连接池优化问题?一、背景随着互联网应用的发展,数据库连接池的优化成为了开发者需要面临的重要问题。在Go语言中,通过使用连接池可以有效地管理和复用数据库连接,提升应用程序在并发访问数据库时的性能。本文将介绍在...
    99+
    2023-10-22
    优化 连接池 并发处理
  • Go语言中如何处理并发数据库连接的连接池优化问题
    在Go语言中,可以使用`database/sql`包来处理数据库连接的连接池优化问题。`database/sql`包提供了`sql....
    99+
    2023-10-09
    Go语言
  • python3线程池ThreadPoolExecutor处理csv文件数据
    目录背景知识点拓展库流程实现代码解释背景 由于不同乙方对服务商业务接口字段理解不一致,导致线上上千万数据量数据存在问题,为了修复数据,通过 Python 脚本进行修改 知识点 Pyt...
    99+
    2024-04-02
  • 数据库连接池管理的艺术:优雅地处理并发请求
    数据库连接池是管理数据库连接的工具,它可以提高数据库访问效率和性能。在高并发的情况下,为了避免数据库服务器过载,需要使用数据库连接池来管理数据库连接。 数据库连接池管理的艺术在于如何在高并发的情况下优雅地处理并发请求。以下是一些技巧: ...
    99+
    2024-02-13
    数据库连接池 并发请求 连接复用 连接泄漏 连接池管理
  • 深入理解Java多线程与并发框(第⑪篇)——线程池参数
    ThreadPoolExecutor线程池线程的创建和销毁都会消耗大量资源,就好像公司每天上午9点工作时就招进一批员工,晚上6点干完活就辞退一批员工,这都会销毁公司大量资源。所以合理利用 “池” 中固定、稳定的线程是非常有必要的。扩展关系T...
    99+
    2023-06-05
  • python线程池并发请求数据问题怎么解决
    在Python中,可以使用concurrent.futures模块中的ThreadPoolExecutor类来创建线程池,并发处理请...
    99+
    2023-10-26
    python
  • java线程池合理设置最大线程数和核心线程数方式
    目录线程池合理设置最大线程数和核心线程数一开始是这么配置的后来网上查询线程池核心数配置最后我是这么配置的线程池核心线程数与最大线程数的区别线程池策略饱和策略线程池合理设置最大线程数和...
    99+
    2024-04-02
  • 线程池大揭秘:释放并发处理的真正潜力
    线程池是一种轻量级的并发处理机制,它能够通过管理一组预先创建的线程来优化并行任务的执行,从而显著提高应用程序的性能。 线程池的优势 提高性能: 线程池通过避免频繁地创建和销毁线程来提高性能,从而减少了开销和延迟。 可扩展性: 线程池允许...
    99+
    2024-03-13
    线程池
  • Java使用线程池批量处理数据操作
    Java使用线程池批量处理数据操作 疑问&思路: 如何保证数据按顺序批量处理 2.如何保证数据全部处理完统一返回 3.如何保证是多任务异步操作 4.如何提高运行效率,减少运行时间 使用ArrayLis...
    99+
    2023-09-08
    java 开发语言
  • Python并发编程:如何优化HTTP请求处理?
    随着互联网的发展,我们的应用程序越来越依赖于HTTP请求。无论是爬取网页、请求API接口还是处理数据,HTTP请求几乎成为了每一个应用程序的必要操作。然而,如果我们在处理HTTP请求时没有考虑并发处理,那么我们的程序可能会因为等待服务器响...
    99+
    2023-09-21
    http 二维码 并发
  • PHP并发编程:如何优化分布式文件处理的性能?
    在分布式系统中,文件处理是一个非常重要的任务。然而,由于文件处理涉及到大量的IO操作,因此很容易成为整个系统的瓶颈。为了充分利用系统资源,我们需要使用并发编程来优化文件处理的性能。在本文中,我们将介绍如何使用PHP并发编程来优化分布式文件...
    99+
    2023-09-22
    并发 文件 分布式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作