【JavaWeb】定时任务和批量插入数据库数据

news2024/11/15 23:21:00

定时任务

需要在项目启动类添加注解开启支持定时任务:

在这里插入图片描述

以下示例是定时任务插入数据的操作:

package com.yupi.yupao.once.importuser;

import com.yupi.yupao.mapper.UserMapper;
import com.yupi.yupao.model.domain.User;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;

/**
 * 导入用户任务
 *
 */
@Component
public class InsertUsers {

    @Resource
    private UserMapper userMapper;

    /**
     * 批量插入用户
     */
     // initialDelay 每隔多少毫秒执行一次 fixedRate 执行的时间间隔 所以两个结合起来可以控制定时任务只执行一次
//    @Scheduled(initialDelay = 5000, fixedRate = Long.MAX_VALUE)
    public void doInsertUsers() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int INSERT_NUM = 1000;
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("假鱼皮");
            user.setUserAccount("fakeyupi");
            user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
            user.setGender(0);
            user.setUserPassword("12345678");
            user.setPhone("123");
            user.setEmail("123@qq.com");
            user.setTags("[]");
            user.setUserStatus(0);
            user.setUserRole(0);
            user.setPlanetCode("11111111");
            userMapper.insert(user);
        }
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}

这种插入方法过程:建立数据库连接会话,插入一条数据,关闭数据库连接会话。如果需要插入非常多条数据,可能等待非常久(1000条90s)。

上述 for 循环插入数据的问题:

  1. 建立和释放数据库连接(批量查询解决)
  2. for 循环是绝对线性的(并发)

并发注意执行的先后顺序无影响,不要使用非并发类的集合。

package com.yupi.yupao.service;

import com.yupi.yupao.model.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 导入用户测试
 *
 */
@SpringBootTest
public class InsertUsersTest {

    @Resource
    private UserService userService;

	// 核心线程数(默认运行的线程数): 40, 最大线程数:1000,存活时间;10000, 单位,任务队列长度:10000
    private ExecutorService executorService = new ThreadPoolExecutor(40, 1000, 10000, TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000));

    /**
     * 批量插入用户
     */
    @Test
    public void doInsertUsers() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 一共插入 10w 条数据
        final int INSERT_NUM = 100000;
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("原_创 【鱼_皮】https://t.zsxq.com/0emozsIJh");
            user.setUserAccount("fakeyupi");
            user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
            user.setGender(0);
            user.setUserPassword("12345678");
            user.setPhone("123");
            user.setEmail("123@qq.com");
            user.setTags("[]");
            user.setUserStatus(0);
            user.setUserRole(0);
            user.setPlanetCode("11111111");
            userList.add(user);
        }
        // 18 秒 10 万条
        // 1w 条为一组
        userService.saveBatch(userList, 10000);
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }

    /**
     * 并发批量插入用户
     */
    @Test
    public void doConcurrencyInsertUsers() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 分 20 组 一组 5000 条
        int batchSize = 5000;
        int j = 0;
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            List<User> userList = new ArrayList<>();
            while (true) {
                j++;
                User user = new User();
                user.setUsername("假鱼皮");
                user.setUserAccount("fakeyupi");
                user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
                user.setGender(0);
                user.setUserPassword("12345678");
                user.setPhone("123");
                user.setEmail("123@qq.com");
                user.setTags("[]");
                user.setUserStatus(0);
                user.setUserRole(0);
                user.setPlanetCode("11111111");
                userList.add(user);
                if (j % batchSize == 0) {
                    break;
                }
            }
            // 异步执行
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                System.out.println("threadName: " + Thread.currentThread().getName());
                userService.saveBatch(userList, batchSize);
            }, executorService);
            futureList.add(future);
        }
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
        // 6 秒 10 万条
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}

用户插入单元测试,注意打包时要删掉或忽略,不然打一次包就插入一次
// CPU 密集型:分配的核心线程数 = CPU - 1
// IO 密集型:分配的核心线程数可以大于 CPU 核数

默认情况下,上述不同的分组组合结果也会不同,而且并不是一组数越大越好,因为线程数如果不自定义的话是默认的,根据不同的电脑,默认分配的线程数是不一样的。

也就是说,一部分线程干了一次活,可能也有一部分线程干了两次活。所以干了两次活的这部分线程就是时间消耗的主要原因。

所以后面我们自定义的线程池可能会提高性能。

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

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

相关文章

软件测试——论坛系统测试用例

功能测试 其他测试 测试用例 用例编号 用例描述 优先级 预置条件 操作步骤 测试数据 预期结果 测试结果Bug ID软件版本测试员SNS_User_Register_001注册成功使用合法的数据成功注册一个新账号P11、已打开注册页面 2、准备一个未注册用户信息1、输入用户昵称 2、输入用户名 3、…

Unity(2022.3.41LTS) - 摄像机

目录 一、基本概念 二、重要属性 三、摄像机模式 四、脚本控制 五、渲染设置 六. 组件详细介绍 一、基本概念 作用&#xff1a;摄像机决定了玩家在游戏中能够看到的内容。它就像是玩家的眼睛&#xff0c;从特定的位置和角度观察场景&#xff0c;并将场景中的物体渲染到屏…

北冥坞“学件”系统

简介 学件由周志华教授在 2016 年提出 [1, 2]。在学件范式下&#xff0c;世界各地的开发者可分享模型至学件基座系统&#xff0c;系统通过有效查搜和复用学件帮助用户高效解决机器学习任务&#xff0c;而无需从零开始构建机器学习模型。 北冥坞是学件的第一个系统性开源实现&…

客户端字符集小于数据库字符集导致乱码

一、现象 使用plsql或者sqlplus客户端 查询某个表的数据库均显示乱码&#xff0c;如下图所示&#xff1a; 二、原因分析 1、查看数据库的字符集 2、查看客户端的字符集 3、比较 数据库的字符集AL16UTF18&#xff08;服务端&#xff09;是大于en_US.UTF-8&#xff08;客户端&…

【Linux】gcc(工具篇)

文章目录 背景知识gcc的使用预处理&#xff08;进行宏替换&#xff09;编译&#xff08;生成汇编&#xff09;汇编&#xff08;生成机器可识别代码&#xff09;连接&#xff08;生成可执行文件或库文件&#xff09; gcc选项函数库函数库一般分为静态库和动态库两种C/C静态库的安…

Python 程序设计基础教程

Python 程序设计基础教程 撰稿人&#xff1a;南星六月雪 第 一 章 变量与简单数据类型 1.1 变量 先来观察以下程序&#xff1a; world "Hello Python!" print(world)world "Hello Python,I love you!" print(world)运行这个程序&#xff0c;将看到两…

一个利用率超高的大数据实验室是如何练成的?

在当今这个数据爆炸的时代&#xff0c;大数据已成为推动各行各业创新与发展的核心动力。一个高效运转、利用率超高的大数据实验室&#xff0c;不仅是技术创新的摇篮&#xff0c;更是企业竞争力的重要体现。那么&#xff0c;如何构建并维持这样一个实验室呢&#xff1f;本文将探…

【机器学习】软输出和硬输出的基本概念和区别、如何选择软输出还是硬输出、联系函数的作用以及线性判别分析和逻辑回归的基本概念(含python代码)

引言 在机器学习中&#xff0c;“软输出”&#xff08;Soft Output&#xff09;和"硬输出"&#xff08;Hard Output&#xff09;是两种不同的预测输出形式&#xff0c;通常用于分类问题中 文章目录 引言一、软输出和硬输出1.1 硬输出&#xff08;Hard Output&#xf…

深入理解C语言指针原理——深入底层机制

概述 在C语言中&#xff0c;指针是处理内存的核心工具。为了更好地理解指针如何工作&#xff0c;我们需要深入了解指针与底层硬件和操作系统之间的交互方式。本文将探讨指针的底层实现、内存布局、以及它们如何影响程序的行为。 内存模型 虚拟内存 现代操作系统为每个进程提…

Java算法—排序篇之快速排序(Quick sort)

快速排序&#xff08;Quick sort&#xff09; 核心思路&#xff1a; 从数列中挑出一个元素&#xff0c;一般都是左边第一个数字&#xff0c;称为 “基准数”;创建两个指针&#xff0c;一个从前往后走&#xff0c;一个从后往前走。先执行后面的指针&#xff0c;找出第一个比基…

io进程----库

目录 一丶定义 二丶分类 1.静态库 2.动态库 三丶静态库制作 四丶动态库制作 总结&#xff1a; 一丶定义 当使用别人的函数时除了包含头文件以外还需要有库 头文件&#xff1a;函数声明、结构体等类型定义、头文件、宏定义、其他头文件等 库&#xff1a;把一些常…

Java 使用QQ邮箱的接收发送功能,入门级教程

进入qq邮箱主页面&#xff0c;点击账号 下滑找到POP3...如果没有开启&#xff0c;需要开启&#xff0c;开启后&#xff0c;点击管理服务 然后点击生成授权码 按照步骤执行完成后&#xff0c;会给你需要的授权码 1.拿到授权码后&#xff0c;导入相关依赖&#xff0c;和yml相关配…

基于STM32开发的智能家居温度控制系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化温度监测与显示风扇/加热器控制Wi-Fi通信与远程监控应用场景 家庭环境的智能温度管理办公楼的节能温控系统常见问题及解决方案 常见问题解决方案结论 1. 引言 随着人们对生活质量…

OZON电子类目解封,OZON新品飙升榜

Ozon电子类目的解封对于商家来说是一个重要的机会&#xff0c;可以重新进入市场并恢复销售。 Ozon电子类目解封选品&#xff1a;m6z.cn/5H6fQR&#xff08;复制浏览器打开&#xff09; Top1 便携式音响 Портативная колонка Bluetooth с караоке м…

多意图指令识别项目调研及整理

多意图算法及专利调研整理 AGIF: An Adaptive Graph-Interactive Framework for Joint Multiple Intent Detection and Slot Filling 短文本多意图解析 https://zhuanlan.zhihu.com/p/405096922 多意图语义解析包括多意图发现MID&#xff08;Multi-intent discovery&#xf…

搭建go开发环境

下载go软件压缩包 解压压缩包到D:/Program Files 验证是否安装成功 配置系统环境变量Path

甄选范文“论软件质量保证及其应用”,软考高级论文,系统架构设计师论文

论文真题 软件质量保证(Software Quality Assurance, SQA)是指为保证软件系统或软件产品充分满足用户要求的质量而进行的有计划、有组织的活动,这些活动贯穿于软件生产的整个生命周期。质量保证人员负责质量保证的计划、监督、记录、分析及报告工作,辅助软件开发人员得到高…

arthas源码刨析:arthas 命令粗谈 dashboard watch retransform (3)

文章目录 dashboardwatchretransform 前面介绍了 arthas 启动相关的代码并聊了聊怎么到一个 shellserver 的建立。 本篇我们来探讨一下几个使用频次非常高的命令是如何实现的。 在开始之前&#xff0c;我们先概要地了解一下 arthas 命令的几个思路。 自定义命令&#xff0c;普通…

【Hexo】hexo-butterfly主题添加非主站提示

本文首发于 ❄️慕雪的寒舍 说明 因为hexo可以很方便的在多个平台上免费部署&#xff0c;为了让自己的博客能uptime更久一段时间&#xff0c;很多老哥都和我一样&#xff0c;把自己的hexo博客在好多个平台上都部署了一份。 但是我一直想要一个功能&#xff0c;就是在别人访问…

可商用插画

可商用插画 https://www.88sheji.cn/favorites/free-illustration