这是一个手写线程池的系列文章,本文包括对线程池的概述与设计的基本结构。如果你感性趣,请继续看下去吧!
声明:本系列文章将引用大量文章作为阅读材料,所有文章均经过本人阅读。阅读文章+跟随这个系列你会收获颇多!无论你是小白还是老手,搭配使用会有奇迹!
概述
线程(Thread)与进程(Process)都是老生常谈的东西,线程池(Thread pool)就是利用池化技术将多个线程集合到一起,已减少资源消耗,提高资源利用率,从而更优雅的使用线程。类似的还有数据库连接池。
打个比方,找个中介管理我的蓝宝坚尼,佛劳瑞,倍嘎题等数百辆豪车(一辆没有…),我要去泡妞的时候就给他们打个电话,让他们送来;开完了给他们打个电话让他们开走。关于洗车,保养,修理都交由这个中介搞并且他们对这些事情的处理非常有经验。
在Java中,线程池的主要实现类是JUC包中的ThreadPoolExecutor
,有关于这个类的详细讲解,建议阅读下面这篇文章:
使用线程池比较普通创建调用线程的好处不言而喻,即省心又省资源,更多线程池的概念与实际应用可以阅读美团技术团队的这片文章:
- 线程池基本概念与实践 — 美团
接下来,我们看一下线程池的基本结构
基本结构
假设现在我们有一个拥有20个线程的线程池,此时,有10个任务交由我们处理。那么我们直接将这10个任务扔进线程池,到底哪个任务使用哪个线程暂且不管,线程池执行完成后也就返回给我们结果。
因此,我们的线程池中一定要存在线程。(废话!)
不妙的是现在,突然一下有100个任务,但我们知道我们线程池里只有20个线程,那应该如果应对?
要解决这个问题,线程池中要存在一个数据结构用来存储任务,当有任务加入时,先进入这个数据结构,池中的线程会从这个结构中拿取并执行任务。即先跑20个,其中有结束的就从数据结构中拿一个继续跑,直到跑完这100个任务。
因此,我们还要创建一个任务队列,来解决任务数大于线程数的问题。
那这个队列的出列有要求吗?答案是可以有,也可以没有。我们可以按照任务的先后顺序弹出任务,也可以规定这些任务的优先级,从而根据优先级弹出。
所以,在队列的实现上最好是可以配置的,以便于我们应用。
总结一下,实现一个线程池,我们需要多个线程,任务队列,并且队列是可配置的。
此外,我们也要思考一下任务的封装。
任务肯定是多种多样的,来自于不同包的函数和未知类型以及值的参数。
因此,使用泛型是必要的,并且面对不同的函数,想要在我们的Task类中运行,还要用到反射。以及未知参数数量要使用可变参数。
如果不了解,可参考以下文章:
好了,做为手造线程池系列的第零篇概述与基本结构就到这里了,我会尽快更新后续文章!
如果你对文章有任何问题,欢迎在下方评论或发送私信。
感谢你的阅读,如果对这个系列感兴趣,请点个赞,加个收藏。你的支持是我创作的最大动力!
如果可以,欢迎Fllow我的GitHub查看我的最新动态,后续代码也会在相应仓库中更新!
CagyJ-GitHub