返回顶部
首页 > 资讯 > 精选 >如何优化Springboot线程池并发处理数据方式
  • 567
分享到

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

2023-06-22 06:06:30 567人浏览 八月长安
摘要

这篇文章给大家分享的是有关如何优化SpringBoot线程池并发处理数据方式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。第一步:首先配置线程基本参数可以放在application.propertes文件种也可以

这篇文章给大家分享的是有关如何优化SpringBoot线程池并发处理数据方式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

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

可以放在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@Configurationpublic 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@Servicepublic class AsyncServiceImpl implements AsyncService {  @Override @Scheduled(cron = " */1 * * * * ? ") @Async("asyncServiceExecutor") public void executeAsync() {  log.info("start executeAsync");        System.out.println("异步线程执行批量插入等耗时任务");        log.info("end executeAsync");   }  }

第五步:测试结果如下

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; @Slf4jpublic 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个任务

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]

感谢各位的阅读!关于“如何优化springboot线程池并发处理数据方式”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

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

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

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

猜你喜欢
  • 如何优化Springboot线程池并发处理数据方式
    这篇文章给大家分享的是有关如何优化Springboot线程池并发处理数据方式的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。第一步:首先配置线程基本参数可以放在application.propertes文件种也可以...
    99+
    2023-06-22
  • Springboot线程池并发处理数据优化方式
    目录第一步:首先配置线程基本参数第二步:让Spring Boot加载第三步:创建一个service接口第四步:编写现实类第五步:测试结果如下第一步:首先配置线程基本参数 可以放在ap...
    99+
    2024-04-02
  • Go语言中如何处理并发数据库连接的连接池优化问题
    在Go语言中,可以使用`database/sql`包来处理数据库连接的连接池优化问题。`database/sql`包提供了`sql....
    99+
    2023-10-09
    Go语言
  • Go语言中如何处理并发数据库连接的连接池优化问题?
    Go语言中如何处理并发数据库连接的连接池优化问题?一、背景随着互联网应用的发展,数据库连接池的优化成为了开发者需要面临的重要问题。在Go语言中,通过使用连接池可以有效地管理和复用数据库连接,提升应用程序在并发访问数据库时的性能。本文将介绍在...
    99+
    2023-10-22
    优化 连接池 并发处理
  • Python并发编程:如何优化HTTP请求处理?
    随着互联网的发展,我们的应用程序越来越依赖于HTTP请求。无论是爬取网页、请求API接口还是处理数据,HTTP请求几乎成为了每一个应用程序的必要操作。然而,如果我们在处理HTTP请求时没有考虑并发处理,那么我们的程序可能会因为等待服务器响...
    99+
    2023-09-21
    http 二维码 并发
  • java 多线程处理大量并发数据
    Java中多线程是一种处理数据的常见方式,它可以同时执行多个线程以提高程序的性能和效率。下面是一个使用多线程处理数据的示例代码: public class DataProcessor { pub...
    99+
    2023-09-07
    java 开发语言
  • PHP并发编程:如何优化分布式文件处理的性能?
    在分布式系统中,文件处理是一个非常重要的任务。然而,由于文件处理涉及到大量的IO操作,因此很容易成为整个系统的瓶颈。为了充分利用系统资源,我们需要使用并发编程来优化文件处理的性能。在本文中,我们将介绍如何使用PHP并发编程来优化分布式文件...
    99+
    2023-09-22
    并发 文件 分布式
  • Java并发编程:如何优化存储大数据?
    在当今数据爆炸的时代,我们面临着处理大量数据的挑战。在Java编程中,处理大数据也是一项重要的任务。然而,由于内存限制和性能问题,存储大数据的处理是一项非常复杂的任务。 在本文中,我们将介绍一些Java并发编程技术,以优化存储大数据的性能...
    99+
    2023-09-26
    并发 存储 大数据
  • linux多线程并发的处理方式有哪些
    在Linux中,有多种方式可以实现多线程并发的处理:1. 使用线程库:Linux提供了一些线程库,如POSIX线程库(pthread...
    99+
    2023-09-27
    linux
  • android多线程并发处理的方式有哪些
    Android多线程并发处理的方式有以下几种:1. 使用Thread类:创建Thread对象,重写run()方法,在run()方法中...
    99+
    2023-09-23
    android
  • mfc多线程并发处理的方式有哪些
    MFC(Microsoft Foundation Classes)是一个基于C++的应用程序框架,用于开发Windows操作系统上的...
    99+
    2024-02-29
    mfc
  • Java日志系统如何优化并发处理?
    日志系统是现代软件开发中必不可少的一部分,它能够记录系统运行时的各种信息,如错误日志、调试信息、性能指标等。在Java应用程序中,日志系统通常是通过Log4j、Logback等第三方库实现的。 然而,在高并发环境下,日志系统的性能会成为一...
    99+
    2023-09-25
    日志 并发 大数据
  • 数据库连接池管理的艺术:优雅地处理并发请求
    数据库连接池是管理数据库连接的工具,它可以提高数据库访问效率和性能。在高并发的情况下,为了避免数据库服务器过载,需要使用数据库连接池来管理数据库连接。 数据库连接池管理的艺术在于如何在高并发的情况下优雅地处理并发请求。以下是一些技巧: ...
    99+
    2024-02-13
    数据库连接池 并发请求 连接复用 连接泄漏 连接池管理
  • PHP如何优化大数据处理?
    PHP作为一种流行的编程语言,被广泛地应用于大数据处理领域。然而,由于PHP是一种解释性语言,其性能与C语言等编译性语言相比较较差。本文将介绍一些PHP优化技巧,帮助您提高PHP在大数据处理方面的性能。 一、选择合适的数据结构 数据结构是一...
    99+
    2023-06-15
    大数据 unix 索引
  • PHP开发中如何优化并发操作和线程安全
    并发操作指的是同时处理多个请求或任务的能力。在PHP开发中,处理并发操作时需要考虑到线程安全性,以确保多个线程之间的数据共享和状态管理的正确性。本文将介绍一些优化并发操作和确保线程安全的技巧,并附上具体的代码示例。一、使用锁机制确保线程安全...
    99+
    2023-10-21
    PHP开发 线程安全 并发操作优化
  • C++并发编程:如何处理线程间通信?
    c++++ 中线程间通信的方法包括:共享内存、同步机制(互斥锁、条件变量)、管道、消息队列。例如,使用互斥锁保护共享计数器:声明互斥锁(m)、共享变量(counter);每个线程通过加锁...
    99+
    2024-05-04
    c++ 并发编程 同步机制
  • C++并发编程:如何进行任务调度和线程池管理?
    任务调度和线程池管理是 c++++ 并发编程中提高效率和可扩展性的关键。任务调度:使用 std::thread 创建新线程。使用 join() 方法加入线程。线程池管理:创建 threa...
    99+
    2024-05-06
    c++ 并发编程
  • PHP并发编程:如何优化数组操作?
    在PHP中,数组是一个非常常见的数据类型。当我们需要进行大量的数组操作时,通常会遇到一些性能问题。为了解决这些问题,我们可以使用一些并发编程技术来优化数组操作。 以下是一些优化数组操作的技巧: 1.使用多线程 在PHP中,我们可以使用多线...
    99+
    2023-08-16
    并发 数组 面试
  • Apache 并发编程如何优化自然语言处理的效率?
    自然语言处理是人工智能领域的重要应用之一,它涉及到语音识别、语义分析、机器翻译等多个方面。随着数据量的不断增加,自然语言处理系统的效率也成为了一个关键问题。本文将介绍如何利用 Apache 并发编程技术来优化自然语言处理的效率。 一、并发...
    99+
    2023-07-22
    自然语言处理 apache 并发
  • Java并发编程中如何应对NumPy数据处理?
    在当今数据驱动的时代,数据处理已成为各个领域不可或缺的一部分。NumPy是Python中用于科学计算的一个基础库,提供了大量的高级数学函数和矩阵操作。但是,在处理大规模数据时,单线程的NumPy往往会导致性能瓶颈。因此,Java并发编程可...
    99+
    2023-10-23
    numy 二维码 并发
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作