首页 > 其他分享 >SpringBoot使用线程池实现异步批量处理任务

SpringBoot使用线程池实现异步批量处理任务

时间:2024-07-08 10:58:10浏览次数:6  
标签:异步 SpringBoot subList 任务 线程 new CPU log

模拟批处理大量数据

@Slf4j
@Component
public class TestFutureService {

    @Autowired
    private TestFutureServiceImpl testFutureServiceImpl;

    /**
     *  多线程的优势:多核CPU使用多线程可以提高CPU的利用率(单核CPU不行,反而降低),可以实现异步调用。
     *
     *  (1)单核CPU同一时间只能处理一个线程,但是速度非常快,造成并行的假象(并发:交替轮流使用资源)
     *      因为一个CPU一次只能执行一条指令,使用多线程或多进程任务,这些任务其实都是并发执行的,操作系统会不断的切换多个任务。
     *      并发:指在同一个时刻做不止一件事情,比如数据库处理请求时,接受了第一个请求但未处理完成,此时也可以接受第二个请求。两个请求任务在处理时间节点上可以有交集。
     *  (2)多核CPU或CPU采用超线程技术的话,每个核心处理一个线程。(并行:多人分工同时处理任务)
     *      并行:指将耗时长的任务,拆解成多个子任务分配到多线程上,并发的执行。
     */

    @PostConstruct
    public void run(){
        runTask();
    }

    public void runTask() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        log.info("开始执行批量处理任务...");
        List<String> dataList = new ArrayList<>();
        for (int i = 0; i < 50000; i++) {
            dataList.add(IdUtils.fastSimpleUUID());
        }
        // 每个线程处理多少条数据
        int capacity = 1000;
        // 计算得出所需的任务数量
        int count = NumberUtil.round(NumberUtil.div(dataList.size(), capacity), 0, RoundingMode.UP).intValue();
        CountDownLatch latch = new CountDownLatch(count);
        // 线程返回的结果集
        List<Future<List<String>>> futureList = new ArrayList<>();
        List<String> subList = new ArrayList<>(capacity);
        int k = 1;
        for (String id : dataList) {
            if (subList.size() >= capacity) {
                futureList.add(testFutureServiceImpl.doTask(subList, latch, k++));
                subList = new ArrayList<>(capacity);
            }
            subList.add(id);
        }
        if(subList.size() > 0){
            futureList.add(testFutureServiceImpl.doTask(subList, latch, k));
        }
        log.info("任务个数:" + count +"|"+ futureList.size());
        try {
            // 方式一:使用CountDownLatch计数器,等待所有任务执行完成
            latch.await();
            for (Future<List<String>> future : futureList) {
                List<String> pList = future.get();
                System.out.println("返回结果:" + pList.size());
            }
            // 方式二:使用轮循方式检查异步任务是否执行完成,特点:不需要计数器
            /**
            boolean bol = true;
            while (bol){
                for (Future<List<String>> future : futureList) {
                    if(future.isDone()){
                        bol = false;
                    } else {
                        bol = true;
                        break;
                    }
                }
                ThreadUtil.sleep(500);
            }
            */
            log.info("任务完成!");
        } catch (InterruptedException e) {
            log.error("处理线程中断异常", e);
        } catch (ExecutionException e) {
            log.error("处理执行异常", e);
        } catch (Exception e) {
            log.error("其它异常", e);
        }
        stopWatch.stop();
        log.info("任务执行耗时(秒):" + stopWatch.getTotalTimeSeconds());
    }
}

定义使用线程池异步处理实现类

@Slf4j
@Component
public class TestFutureServiceImpl {

    // 需要自定义threadPoolTaskExecutor线程池配置,自行实现
    @Async("threadPoolTaskExecutor")
    public Future<List<String>> doTask(List<String> list, CountDownLatch latch, int k) {
        log.info("开始执行任务:" + k + "|" + list.size());
        ThreadUtil.sleep(1, TimeUnit.SECONDS);
        latch.countDown();
        return new AsyncResult<>(list);
    }
}

标签:异步,SpringBoot,subList,任务,线程,new,CPU,log
From: https://www.cnblogs.com/zhaojinhui/p/18289476

相关文章

  • SpringBoot集成Mongodb文档数据库
    添加Maven依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>配置Mongodb连接信息spring:data:mongodb:host:10.30.29.246......
  • 课程设计-基于Springboot+Vue的网上商城购物系统的设计与实现(源码+LW+包运行)
    源码获取地址:https://download.csdn.net/download/u011832806/89426605系统演示视频:链接:https://pan.baidu.com/s/1p9Xv9VrlNXSyNXRkdhccPg?pwd=xfdy一.系统概述网上商城购物系统主要是为了提高工作人员的工作效率和更方便快捷的满足用户,更好存储所有数据信息及快速方......
  • SpringBoot整合Radis(redis启用,maven依赖,及具体实用)
    文章目录1、本地下载redis并且开启2、导入maven依赖3、添加application.properties4、创建配置类RedisConfig.java5、使用1、注解1、@Cacheable(value="",key="")2、**@CachePut**(value="",key="")3、CacheEvict(value="",key="")2、示例1、本地下......
  • 基于springboot + vue3 +遗传算法的智能组卷在线考试系统的设计与开发
    目录一、项目介绍1、项目简介 二、项目实现1、数据库设计E-R图2、数据库级联思路3、SpringSecurity的认证思路......
  • SpringBoot项目开发中公共字段的处理
    序言在SpringBoot项目开发中,会存在许多重复的公共字段,例如:字段名create_time创建时间update_time更新时间create_user创建操作人update_user更新操作人对于以上四个字段,需要大量的重复代码来实现,比较繁琐......
  • 多线程网络实战之仿qq群聊的服务器和客户端
    目录一、前言二、设计需求1.服务器需求 2.客户端需求三、服务端设计1.项目准备 2.初始化网络库3.SOCKET创建服务器套接字4. bind绑定套接字 5.listen监听套接字 6.accept接受客户端连接7.建立套接字数组8.建立多线程与客户端通信9.处理线程函数,收消息......
  • 异步优化与数据入库:顶点小说爬虫进阶实战
    顶点小说进阶建议这篇顶点小说进阶包括(数据入库、异步爬虫)看之前可以先看我之前发布的文章(从零开始学习Python爬虫:顶点小说全网爬取实战)入库#入库defsave_to_mysql(db_name,table_name,table_column_str,table_info_str):db=pymysql.connect(user='host',passw......
  • 基于微信小程序+Springboot校园二手商城系统设计和实现
    \n文末获取源码联系感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询一、前言介绍:在当今社会的高速发展过程中,产生的劳动力越来越大,提高人们的生活水平和质量,尤其计算机科技的进步,数据和信息以人兴化为本的目的,给人们提供优质的服务,其......
  • ThreadPoolExecutor - 管理线程池的核心类
    下面是使用给定的初始参数创建一个新的ThreadPoolExecutor(构造方法)。publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitun......
  • 基于SpringBoot+Vue+uniapp的随心淘网管理系统(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......