Java 多线程批量处理数据

news/2024/7/3 2:41:45

1 需求
在项目开发中需要处理100万多的数据,这些数据需要从mysql数据库中读取出来,再通过调用其他平台的接口推送数据。由于时间紧迫,数据需要在短时间内完成推送,采用单线程推送很慢,所以采用多线程推送来提高效率。

2 配置多线程
2.1 application.yml

thread-pool:
  core-pool-size: 4
  max-pool-size: 16
  queue-capacity: 80
  keep-alive-seconds: 120

2.2 创建ThreadPoolProperties

import lombok.Data;
import org.springframework.stereotype.Component;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@Component
@ConfigurationProperties(prefix = "thread-pool")
public class ThreadPoolProperties {
    /**
     * 线程池创建时候初始化的线程数
     */
    private int corePoolSize;

    /**
     * 线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
     */
    private int maxPoolSize;

    /**
     * 用来缓冲执行任务的队列
     */
    private int queueCapacity;

    /**
     * 允许线程的空闲时间:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
     */
    private int keepAliveSeconds;
}

2.3 创建ThreadPoolConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@EnableAsync
@Configuration
public class ThreadPoolConfig {
    private final ThreadPoolProperties threadPoolProperties;

    @Autowired
    public ThreadPoolConfig(ThreadPoolProperties threadPoolProperties) {
        this.threadPoolProperties = threadPoolProperties;
    }

    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
        executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
        executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
        executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
        executor.setThreadNamePrefix("thread-pool-");
        return executor;
    }
}

3 多线程批量数据处理

public RequestResult multiThreadPush() {
    List<HistoryStudent> historyStudentList = historyStudentMapper.getList(0, 65867);
    // 分割集合
    List<List<HistoryStudent>> partitionData = partitionData(historyStudentList, 4);

    ThreadPoolTaskExecutor executor = SpringUtil.getBean("threadPoolTaskExecutor", ThreadPoolTaskExecutor.class);
  	// 计数器
    CountDownLatch latch = new CountDownLatch(partitionData.size());

    for (List<HistoryStudent> historyStudents : partitionData) {
        executor.execute(() -> {
            try {
                for (HistoryStudent historyStudent : historyStudents) {
                	// 单个数据处理
                    //processSingleData(historyStudent);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });
    }

    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    return RequestResult.success();
}
private List<List<HistoryStudent>> partitionData(List<HistoryStudent> dataList, int partitionSize) {
    List<List<HistoryStudent>> partitions = new ArrayList<>();

    int size = dataList.size();
    int batchSize = size / partitionSize;

    for (int i = 0; i < partitionSize; i++) {
        int fromIndex = i * batchSize;
        int toIndex = (i == partitionSize - 1) ? size : fromIndex + batchSize;

        partitions.add(dataList.subList(fromIndex, toIndex));
    }

    return partitions;
}

4 参考博客
Java多线程批量处理、线程池的使用
Java多线程处理大批量数据
java多线程批量处理数据


http://lihuaxi.xjx100.cn/news/1761456.html

相关文章

官宣:博士后扩招!

10月26日&#xff0c;《党的十八大以来博士后事业发展综述》发布&#xff0c;其中显示&#xff0c;十八大以来&#xff0c;博士后招收培养规模逐年扩大&#xff0c;博士后进站人数由2012年的1.25万人增长到2022年的3.2万人&#xff0c;2021年、2022年连续两年突破3万人。 图片来…

webgoat-Broken Access ControlI 访问控制失效

Insecure Direct Object References不安全的直接对象引用 直接对象引用 直接对象引用是指应用程序使用客户端提供的输入来访问数据和对象。 例子 使用 GET 方法的直接对象引用示例可能如下所示 https://some.company.tld/dor?id12345 https://some.company.tld/images?img…

2023.11.6 Spring 使用注解存储 Bean 对象

目录 前置工作 使用类注解 五大类注解 Controller&#xff08;控制器&#xff09; Service&#xff08;服务&#xff09; Repository&#xff08;仓库&#xff09; Component&#xff08;组件&#xff09; Configuration&#xff08;配置&#xff09; 使用方法注解 B…

种子公司展示预约小程序的作用如何

蔬菜水果育苗种子&#xff0c;各种农作物是生活所需&#xff0c;各地的种子公司或经销商往往有很高需求度&#xff0c;无论产品还是服务/知识往往需要的用户很多&#xff0c;但在实际经营中&#xff0c;商家也还是会面对一些痛点&#xff1a; 1、品牌传播产品展示难 种子经销…

SLAM从入门到精通(车道线检测)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于slam而言&#xff0c;大家一般想到的就是去通过传感器找特征点&#xff0c;进而借助于特征点去定位机器人的位置。但是对于用户或者厂家来说&a…

什么是微服务?与分布式又有什么区别?

什么是微服务&#xff0c;我们先从传统的单体结构进行了解&#xff0c;对两者进行对比。 单体结构 单体结构是一种传统的软件架构模式&#xff0c;它将应用程序划分为一组相互依赖的模块和组件。这些模块和组件通常都是构建在同一个平台上的&#xff0c;并且紧密耦合在一起。…

通信原理板块——基础知识系列目录索引

目录索引&#xff0c;顾名思义&#xff0c;为了方便读者对此系列文章进行回顾与复习。 具体操作方式&#xff0c;读者可根据文章内容目录&#xff0c;进行针对性的知识回顾与学习&#xff0c;微信复制并打开对应文章的索引链接&#xff0c;跳转至对应文章的详细内容。 本节目录…

【广州华锐互动】影视制作VR在线学习:身临其境,提高学习效率

随着科技的不断发展&#xff0c;影视后期制作技术也在日新月异。然而&#xff0c;传统的教学方式往往难以满足学员的学习需求&#xff0c;无法充分展现影视后期制作的魅力和潜力。近年来&#xff0c;虚拟现实(VR)技术的崛起为教学领域带来了新的机遇。通过VR教学课件&#xff0…