
如何管理Java线程池及搭建分布式Hadoop调度框架
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头。怎么做一套简便的线程开发模式框架让大家从单线程开发快速转入多线程开发,这确实是个比较难搞的工程。
那具体什么是线程呢?首先看看进程是什么,进程就是系统中执行的一个程序,这个程序可以使用内存、处理器、文件系统等相关资源。例如QQ软件、Eclipse、Tomcat等就是一个exe程序,运行启动起来就是一个进程。为什么需要多线程?如果每个进程都是单独处理一件事情不能多个任务同时处理,比如我们打开qq只能和一个人聊天,我们用eclipse开发代码的时候不能编译代码,我们请求tomcat服务时只能服务一个用户请求,那我想我们还在原始社会。多线程的目的就是让一个进程能够同时处理多件事情或者请求。比如现在我们使用的QQ软件可以同时和多个人聊天,我们用eclipse开发代码时还可以编译代码,tomcat可以同时服务多个用户请求。
线程这么多好处,怎么把单进程程序变成多线程程序呢?不同的语言有不同的实现,这里说下java语言的实现多线程的两种方式:扩展java.lang.Thread类、实现java.lang.Runnable接口。
先看个例子,假设有100个数据需要分发并且计算。看下单线程的处理速度:
package thread;import java.util.Vector;public class OneMain { public static void main(String[] args) throws InterruptedException { Vector<Integer> list = new Vector<Integer>(100); for (int i = 0; i < 100; i++) { list.add(i); } long start = System.currentTimeMillis(); while (list.size() > 0) { int val = list.remove(0); Thread. sleep(100);//模拟处理 System. out.println(val); } long end = System.currentTimeMillis(); System. out.println("消耗 " + (end - start) + " ms"); } // 消耗 10063 ms}
再看一下多线程的处理速度,采用了10个线程分别处理:
package thread; import java.util.Vector; import java.util.concurrent.CountDownLatch; public class MultiThread extends Thread { static Vector<Integer> list = new Vector<Integer>(100); static CountDownLatch count = new CountDownLatch(10); public void run() { while (list.size() > 0) { try { int val = list.remove(0); System.out.println(val); Thread.sleep(100);//模拟处理 } catch (Exception e) { // 可能数组越界,这个地方只是为了说明问题,忽略错误 } } count.countDown(); // 删除成功减一 } public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 100; i++) { list.add(i); } long start = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { new MultiThread().start(); } count.await(); long end = System.currentTimeMillis(); System.out.println("消耗 " + (end - start) + " ms"); } // 消耗 1001 ms}
大家看到了线程的好处了吧!单线程需要10S,10个线程只需要1S。充分利用了系统资源实现并行计算。也许这里会产生一个误解,是不是增加的线程个数越多效率越高。线程越多处理性能越高这个是错误的,范式都要合适,过了就不好了。需要普及一下计算机硬件的一些知识。我们的cpu是个运算器,线程执行就需要这个运算器来运行。不过这个资源只有一个,大家就会争抢。一般通过以下几种算法实现争抢cpu的调度:
这三种算法都有优缺点,实际操作系统是结合多种算法,保证优先级的能够先处理,但是也不能一直处理优先级的任务。硬件方面为了提高效率也有多核cpu、多线程cpu等解决方案。目前看得出来线程增多了会带来cpu调度的负载增加,cpu需要调度大量的线程,包括创建线程、销毁线程、线程是否需要换出cpu、是否需要分配到cpu。这些都是需要消耗系统资源的,由此,我们需要一个机制来统一管理这一堆线程资源。线程池的理念提出解决了频繁创建、销毁线程的代价。线程池指预先创建好一定大小的线程等待随时服务用户的任务处理,不必等到用户需要的时候再去创建。特别是在java开发中,尽量减少垃圾回收机制的消耗就要减少对象的频繁创建和销毁。
之前我们都是自己实现的线程池,不过随之jdk1.5的推出,jdk自带了java.util.concurrent并发开发框架,解决了我们大部分线程池框架的重复工作。可以使用Executors来建立线程池,列出以下大概的,后面再介绍。
有了线程池后有以下几个问题需要考虑:
考虑到这几点,我们需要把线程集中管理起来,用java.util.concurrent是做不到的。需要做以下几点:
组件图为:
构建好线程调度框架是不是就可以应对大量计算的需求了呢?答案是否定的。因为一个机器的资源是有限的,上面也提到了cpu是时间周期的,任务一多了也会排队,就算增加cpu,一个机器能承载的cpu也是有限的。所以需要把整个线程池框架做成分布式的任务调度框架才能应对横向扩展,比如一个机器上的资源达到瓶颈了,马上增加一台机器部署调度框架和业务就可以增加计算能力了。好了,如何搭建?如下图:
基于jeeframework我们封装spring、ibatis、数据库等操作,并且可以调用业务方法完成业务处理。主要组件为:
一般这个架构可以应对常用的分布式处理需求了,不过有个缺陷就是随着开发人员的增多和业务模型的增多,单线程的编程模型也会变得复杂。比如需要对1000w数据进行分词,如果这个放到一个线程里来执行,不算计算时间消耗光是查询数据库就需要耗费不少时间。有人说,那我把1000w数据打散放到不同机器去运算,然后再合并不就行了吗?因为这是个特例的模式,专为了这个需求去开发相应的程序没有问题,但是以后又有其他的海量需求如何办?比如把倒退3年的所有用户发的帖子中发帖子最多的粉丝转发的最高的用户作息时间取出来。又得编一套程序实现,太麻烦!分布式云计算架构要解决的就是这些问题,减少开发复杂度并且要高性能,大家会不会想到一个最近很热的一个框架,hadoop,没错就是这个玩意。hadoop解决的就是这个问题,把大的计算任务分解、计算、合并,这不就是我们要的东西吗?不过玩过这个的人都知道他是一个单独的进程。不是!他是一堆进程,怎么和我们的调度框架结合起来?看图说话:
基本前面的分布式调度框架组件不变,增加如下组件和功能:
这样,整个改造基本完成。不过需要注意的是架构设计一定要减少开发程序的复杂度。这里虽然引入了hadoop模型,但是框架上开发者还是隐藏的。业务处理类既可以在单机模式下运行也可以在hadoop上运行,并且可以调用spring、ibatis。减少了开发的学习成本,在实战中慢慢体会就学会了 一项新技能。
界面截图:
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
左偏态分布转正态分布:方法、原理与实践 左偏态分布转正态分布:方法、原理与实践 在统计分析、数据建模和科学研究中,正态分 ...
2025-07-21CDA 数据分析师的职业生涯规划:从入门到卓越的成长之路 在数字经济蓬勃发展的当下,数据已成为企业核心竞争力的重要来源,而 CD ...
2025-07-21MySQL执行计划中rows的计算逻辑:从原理到实践 MySQL 执行计划中 rows 的计算逻辑:从原理到实践 在 MySQL 数据库的查询优化中 ...
2025-07-21在AI渗透率超85%的2025年,企业生存之战就是数据之战,CDA认证已成为决定企业存续的生死线!据麦肯锡全球研究院数据显示,AI驱 ...
2025-07-2035岁焦虑像一把高悬的利刃,裁员潮、晋升无望、技能过时……当职场中年危机与数字化浪潮正面交锋,你是否发现: 简历投了10 ...
2025-07-20CDA 数据分析师报考条件详解与准备指南 在数据驱动决策的时代浪潮下,CDA 数据分析师认证愈发受到瞩目,成为众多有志投身数 ...
2025-07-18刚入职场或是在职场正面临岗位替代、技能更新、人机协作等焦虑的打工人,想要找到一条破解职场焦虑和升职瓶颈的系统化学习提升 ...
2025-07-182025被称为“AI元年”,而AI,与数据密不可分。网易公司创始人丁磊在《AI思维:从数据中创造价值的炼金术 ...
2025-07-18CDA 数据分析师:数据时代的价值挖掘者 在大数据席卷全球的今天,数据已成为企业核心竞争力的重要组成部分。从海量数据中提取有 ...
2025-07-18SPSS 赋值后数据不显示?原因排查与解决指南 在 SPSS( Statistical Package for the Social Sciences)数据分析过程中,变量 ...
2025-07-18在 DBeaver 中利用 MySQL 实现表数据同步操作指南 在数据库管理工作中,将一张表的数据同步到另一张表是常见需求,这有助于 ...
2025-07-18数据分析师的技能图谱:从数据到价值的桥梁 在数据驱动决策的时代,数据分析师如同 “数据翻译官”,将冰冷的数字转化为清晰的 ...
2025-07-17Pandas 写入指定行数据:数据精细化管理的核心技能 在数据处理的日常工作中,我们常常需要面对这样的场景:在庞大的数据集里精 ...
2025-07-17解码 CDA:数据时代的通行证 在数字化浪潮席卷全球的今天,当企业决策者盯着屏幕上跳动的数据曲线寻找增长密码,当科研人员在 ...
2025-07-17CDA 精益业务数据分析:数据驱动业务增长的实战方法论 在企业数字化转型的浪潮中,“数据分析” 已从 “加分项” 成为 “必修课 ...
2025-07-16MySQL 中 ADD KEY 与 ADD INDEX 详解:用法、差异与优化实践 在 MySQL 数据库表结构设计中,索引是提升查询性能的核心手段。无论 ...
2025-07-16解析 MySQL Update 语句中 “query end” 状态:含义、成因与优化指南 在 MySQL 数据库的日常运维与开发中,开发者和 DBA 常会 ...
2025-07-16如何考取数据分析师证书:以 CDA 为例 在数字化浪潮席卷各行各业的当下,数据分析师已然成为企业挖掘数据价值、驱动决策的 ...
2025-07-15CDA 精益业务数据分析:驱动企业高效决策的核心引擎 在数字经济时代,企业面临着前所未有的数据洪流,如何从海量数据中提取有 ...
2025-07-15MySQL 无外键关联表的 JOIN 实战:数据整合的灵活之道 在 MySQL 数据库的日常操作中,我们经常会遇到需要整合多张表数据的场景 ...
2025-07-15