AI 助理
备案 控制台
开发者社区 开发与运维 文章 正文

使用线程池多线程优化大数据量项目 ✨ 每日积累

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 使用线程池多线程优化大数据量项目 ✨ 每日积累

背景


当项目中有获取n个模块的信息,之后进行多个模块信息合并的操作,可以使用多线程来实现,开启多个异步线程哪区多个模块数据。例如获取用户基础信息和获取用户账号信息,他们分别处于不同的表或者不同的数据库中。


图示如下


1.png

模拟代码

用户合并信息bean

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
public class UserInfo implements Serializable {
    private int userId;
    private String userName;
    private String sex;
    private int age;
    private String password;
    private String hobby;
    private String phoneNumber;
    private BigInteger accountId;
    private BigDecimal accountDeposit;
    private String bankOfAccountId;
    private UserInfo(UserBuilder userBuilder){
        this.userId = userBuilder.userBaseInfo.getUserId();
        if (userBuilder.userBaseInfo.getUserName() != null) this.userName = userBuilder.userBaseInfo.getUserName();
        if (userBuilder.userBaseInfo.getSex() != null) this.sex = userBuilder.userBaseInfo.getSex();
        this.age = userBuilder.userBaseInfo.getAge();
        if (userBuilder.userBaseInfo.getHobby() != null)this.hobby = userBuilder.userBaseInfo.getHobby();
        if (userBuilder.userBaseInfo.getPassword() != null) this.password = userBuilder.userBaseInfo.getPassword();
        if (userBuilder.userBaseInfo.getPhoneNumber() != null) this.phoneNumber = userBuilder.userBaseInfo.getPhoneNumber();
        if (userBuilder.userAccountInfo.getAccountId() != null) this.accountId = userBuilder.userAccountInfo.getAccountId();
        if (userBuilder.userAccountInfo.getBankOfAccountId() != null) this.bankOfAccountId = userBuilder.userAccountInfo.getBankOfAccountId();
        if (userBuilder.userAccountInfo.getAccountDeposit() != null) this.accountDeposit = userBuilder.userAccountInfo.getAccountDeposit();
    }
    /**
     * BeanBuilder能保证像重叠构造器模式那样的安全性,
     * 也能保证像JavaBeans模式那么好的可读性。这就是Builder模式的一种形式,
     * 不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),
     * 得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,
     * 来设置每个相关的可选参数。最后,客户端调用无参的builder方法来生成不可变的对象。
     * 这个builder是它构建类的静态成员类。
     *
     */
    public static class UserBuilder{
        private UserBaseInfo userBaseInfo;
        private UserAccountInfo userAccountInfo;
        public UserBuilder() {
        }
        public UserBuilder userBaseInfo(UserBaseInfo val) {
            this.userBaseInfo = val;
            return this;
        }
        public UserBuilder userAccountInfo(UserAccountInfo val) {
            this.userAccountInfo = val;
            return this;
        }
        public UserInfo build() {
            return new UserInfo(this);
        }
    }
}

用户基础信息bean

public class UserBaseInfo {
    private int userId;
    private String userName;
    private String sex;
    private int age;
    private String password;
    private String hobby;
    private String phoneNumber;
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getHobby() {
        return hobby;
    }
    public void setHobby(String hobby) {
        this.hobby = hobby;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

用户账号信息bean

import java.math.BigDecimal;
import java.math.BigInteger;
public class UserAccountInfo {
    private int userId;
    private BigInteger accountId;
    private BigDecimal accountDeposit;
    private String bankOfAccountId;
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public BigInteger getAccountId() {
        return accountId;
    }
    public void setAccountId(BigInteger accountId) {
        this.accountId = accountId;
    }
    public BigDecimal getAccountDeposit() {
        return accountDeposit;
    }
    public void setAccountDeposit(BigDecimal accountDeposit) {
        this.accountDeposit = accountDeposit;
    }
    public String getBankOfAccountId() {
        return bankOfAccountId;
    }
    public void setBankOfAccountId(String bankOfAccountId) {
        this.bankOfAccountId = bankOfAccountId;
    }
}

用户service接口

import java.util.List;
public interface UserService {
    List<UserBaseInfo> getUserInfos();
    List<UserAccountInfo> getUserAccountInfos();
}

用户service接口实现类

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements UserService{
    @Override
    public List<UserBaseInfo> getUserInfos() {
        Long startTime = System.currentTimeMillis();
        List<UserBaseInfo> userBaseInfoList = new ArrayList<>();
        UserBaseInfo userBaseInfo = null;
        for (int i = 0; i < 5000; i++) {
            userBaseInfo = new UserBaseInfo();
            userBaseInfo.setUserId(i);
            userBaseInfo.setUserName("测试账号" + i);
            userBaseInfo.setAge(18);
            userBaseInfo.setHobby("唱、跳、rap、篮球");
            userBaseInfo.setPassword("Test123!=" + i);
            userBaseInfo.setPhoneNumber("13111111111");
            userBaseInfo.setSex("无");
            userBaseInfoList.add(userBaseInfo);
        }
        System.out.println("userBaseInfoList size:" + userBaseInfoList.size());
        System.out.println("获取用户base信息用时:" + (System.currentTimeMillis() - startTime));
        return userBaseInfoList;
    }
    @Override
    public List<UserAccountInfo> getUserAccountInfos() {
        Long startTime = System.currentTimeMillis();
        List<UserAccountInfo> userAccountInfoList = new ArrayList<>();
        UserAccountInfo userAccountInfo = null;
        for (int i = 0; i < 5000; i++) {
            userAccountInfo = new UserAccountInfo();
            userAccountInfo.setUserId(i);
            userAccountInfo.setAccountId(new BigInteger(String.valueOf(10000000 + i)));
            userAccountInfo.setAccountDeposit(new BigDecimal("1314520" + i));
            userAccountInfo.setBankOfAccountId("中国银行");
            userAccountInfoList.add(userAccountInfo);
        }
        System.out.println("获取用户account信息用时:" + (System.currentTimeMillis() - startTime));
        return userAccountInfoList;
    }
}

模拟客户端测试

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class TestClient {
    public static void main(String[] args) {
        final UserService userBaseService = new UserServiceImpl();
        long startTime = System.currentTimeMillis();
        //单线程串行运行
        //获取用户账户基本信息
        List<UserAccountInfo> userAccountInfos = userBaseService.getUserAccountInfos();
        //获取用户基本信息
        List<UserBaseInfo> userInfos = userBaseService.getUserInfos();
        System.out.println("单线程获取用户信息运行耗时:" + (System.currentTimeMillis() - startTime));
        //合并用户账号和基本信息来完善用户信息
        List<UserInfo> userInfoList = new ArrayList<>();
        setUserInfoList(userAccountInfos, userInfos, userInfoList);
        //清空list
        userInfoList.clear();
        System.out.println("-------------------------");
        long startTimeV2 = System.currentTimeMillis();
        //自定义线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        List<UserBaseInfo> userBaseInfoList = new ArrayList<>();
        List<UserAccountInfo> userAccountInfoArrayList = new ArrayList<>();
        try {
            userBaseInfoList = threadPoolExecutor.submit(new Callable<List<UserBaseInfo>>() {
                @Override
                public List<UserBaseInfo> call() throws Exception {
                    return userBaseService.getUserInfos();
                }
            }).get(); //阻塞主线程,等待线程池线程执行完毕
            userAccountInfoArrayList = threadPoolExecutor.submit(new Callable<List<UserAccountInfo>>() {
                @Override
                public List<UserAccountInfo> call() throws Exception {
                    return userBaseService.getUserAccountInfos();
                }
            }).get();//阻塞主线程,等待线程池线程执行完毕
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        threadPoolExecutor.shutdown();
        System.out.println("多线程运行耗时:" + (System.currentTimeMillis() - startTimeV2));
        setUserInfoList(userAccountInfoArrayList, userBaseInfoList, userInfoList);
    }
    /**
     * 用户完整信息装配
     * @param userAccountInfos
     * @param userBaseInfos
     * @param userInfoList
     */
    public static void setUserInfoList(List<UserAccountInfo> userAccountInfos,  List<UserBaseInfo> userBaseInfos, List<UserInfo> userInfoList){
        Long startTime = System.currentTimeMillis();
        userBaseInfos.stream().forEach(userInfo -> {
            userAccountInfos.stream().forEach(userAccountInfo -> {
                if (userInfo.getUserId() == userAccountInfo.getUserId()) {
                    userInfoList.add(new UserInfo.UserBuilder().userBaseInfo(userInfo).userAccountInfo(userAccountInfo).build());
                }
            });
        });
//        for (int i = 0; i < userBaseInfos.size(); i++) {
//            for (int i1 = i; i1 < userAccountInfos.size(); i1++) {
//                if (userBaseInfos.get(i).getUserId() == userAccountInfos.get(i1).getUserId()) {
//                    userInfoList.add(new UserInfo.UserBuilder().userBaseInfo(userBaseInfos.get(i)).userAccountInfo(userAccountInfos.get(i1)).build());
//                }
//            }
//        }
        System.out.println("用户完整信息装配花费:" + (System.currentTimeMillis() - startTime));
    }
}

运行结果

1.png

如上图所示,如果是大数据量下,优化效果是很显著的,使用自定义线程池、Callable和FutureTask结合使用,FutureTask中有get()方法,能阻塞住线程,等执行完了返回一个结果,主线程拿到结果才能继续往下执行。
相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
力不竭战不止
目录
相关文章
阿里云开发者
|
10天前
|
SQL 分布式计算 运维
如何对付一个耗时6h+的ODPS任务:慢节点优化实践
本文描述了大数据处理任务(特别是涉及大量JOIN操作的任务)中遇到的性能瓶颈问题及其优化过程。
阿里云开发者
29 2
程序员小海绵
|
5天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
程序员小海绵
59 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
Ant.Dream
|
6天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
Ant.Dream
25 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
Ant.Dream
|
8天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
Ant.Dream
27 10
游客qf4jmczx4xu2y
|
8天前
|
Java Android开发 开发者
安卓应用开发中的线程管理优化技巧
【9月更文挑战第10天】在安卓开发的海洋里,线程管理犹如航行的风帆,掌握好它,能让应用乘风破浪,反之则可能遭遇性能的暗礁。本文将通过浅显易懂的语言和生动的比喻,带你探索如何优雅地处理安卓中的线程问题,从基础的线程创建到高级的线程池运用,让你的应用运行更加流畅。
游客qf4jmczx4xu2y
23 3
智物科技库
|
15天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
智物科技库
20 6
可能只会写BUG
|
15天前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
可能只会写BUG
28 3
最好zzz
|
16天前
|
监控 Java
线程池中线程异常后:销毁还是复用?技术深度剖析
在并发编程中,线程池作为一种高效利用系统资源的工具,被广泛用于处理大量并发任务。然而,当线程池中的线程在执行任务时遇到异常,如何妥善处理这些异常线程成为了一个值得深入探讨的话题。本文将围绕“线程池中线程异常后:销毁还是复用?”这一主题,分享一些实践经验和理论思考。
最好zzz
30 3
东方睿赢
|
17天前
|
C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【9月更文挑战第2天】
东方睿赢
44 4
小王老师呀
|
5天前
|
SQL 存储 监控
SQLServer事务复制延迟优化之并行(多线程)复制
【9月更文挑战第12天】在SQL Server中,事务复制延迟会影响数据同步性。并行复制可通过多线程处理优化这一问题,提高复制效率。主要优化方法包括:配置分发代理参数、优化网络带宽、调整系统资源、优化数据库设计及定期监控维护。合理实施这些措施可提升数据同步的及时性和可靠性。
小王老师呀
10 0

热门文章

最新文章

  • 1
    后Hadoop时代,我们该如何去架构自己的大数据平台
  • 2
    Hadoop迁移MaxCompute神器之DataX-On-Hadoop使用指南
  • 3
    使用MaxCompute访问TableStore(OTS) 简明手册
  • 4
    MaxCompute规格详解--合理的选择让您花更低的成本获得更高的业务价值
  • 5
    医学影像大数据时代下,将如何推动智能化医疗发展?
  • 6
    【云端大数据实战】大数据误区、大数据处理步骤分析
  • 7
    传大数据先锋Cloudera计划今年晚些时候上市
  • 8
    阿里云大数据ACA及ACP复习题(241~250)
  • 9
    MaxCompute安装Eclipse开发插件
  • 10
    师北宸:小机器成就大数据
  • 1
    C#学习系列相关之多线程(五)----线程池ThreadPool用法
    61
  • 2
    【java进阶】Java中线程的实现方式
    49
  • 3
    深入理解 Java 多线程、Lambda 表达式及线程安全最佳实践
    174
  • 4
    【C++】—— C++11之线程库
    73
  • 5
    C/C++ 线程超详细讲解(系统性学习day10)
    58
  • 6
    Swing通过后台线程实现页面更新
    58
  • 7
    Java中的线程安全集合
    173
  • 8
    浅析Python自带的线程池和进程池
    392
  • 9
    Python使用多线程解析超大日志文件
    143
  • 10
    3段代码详解python中的单线程、多线程和多进程
    80
  • 相关课程

    更多
  • 大数据Spark2020最新课程(知识精讲与实战演练)第二阶段
  • 大数据Spark2020版(知识精讲与实战演练)第三阶段
  • 大数据Spark2020版(知识精讲与实战演练)第四阶段
  • 2020版大数据实战项目之DMP广告系统(第三阶段)
  • 2020版大数据实战项目之DMP广告系统(第四阶段)
  • 2020版大数据实战项目之DMP广告系统(第七阶段)
  • 相关电子书

    更多
  • Data+AI时代大数据平台应该如何建设
  • 大数据AI一体化的解读
  • 极氪大数据 Serverless 应用实践
  • 相关实验场景

    更多
  • 通过FastMR自动拉起大数据集群并运行TPCDS任务
  • 基于MaxCompute的热门话题分析
  • 高性能特性体验:ePQ 的详解与实战
  • 实时数据及离线数据上云方案
  • 下一篇
    基于LNMP搭建WordPress

    天下网标王保定网站搜索优化多少钱闵行区优化网站价格怎么做网站优化排名武穴网站关键词优化网站排名优化ね需宙斯不错徐州网站权重优化产品优化网站推广seo网站优化学校薛城网站优化网站优化快照六安专业网站优化伊春市网站seo优化排名平乡网站优化招远集团网站优化公司十堰低成本网站优化哪家好西安网站优化公司地址公司黄浦区官方网站优化方案定制松江区企业网站优化定制网站搜索引擎优化哪家好电商网站优化制作新绛网站优化方式方法常州网站seo站内优化费用咸宁网站优化关键词排名在线网站优化服务如何新泰市网站优化哪里有专业网站优化价格是多少钱什么人需要网站优化增城外贸网站优化推广费用网站seo网页标题优化肇庆网站优化怎么做香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

    天下网标王 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化