首先感谢Sam老师的公开课,让鄙人对线程池有一些深刻的体会,接下来咱们聊一下线程池:
1. 什么是线程池?
将他分开理解, 线程我前面有过介绍,接下来就是池。
总归为:池化技术 ---》数据库连接池 缓存架构 缓存池 线程池 内存池,连接池,这种思想演变成缓存架构技术---> JDK设计思想有千丝万缕的联系
池化技术 - 简单点来说,就是提前保存大量的资源,以备不时之需。
对于线程,内存,oracle的连接对象等等,这些都是资源,程序中当你创建一个线程或者在堆上申请一块内存时,都涉及到很多系统调用,也是非常消耗CPU的,如果你的程序需要很多类似的工作线程或者需要频繁的申请释放小块内存,
如果没有在这方面进行优化,那很有可能这部分代码将会成为影响你整个程序性能的瓶颈。
池化技术主要有线程池,内存池,连接池,对象池等等,
池:就是提供同一类型的服务对象的集合。
那么线程池无非也就是:提供线程执行对象的集合。
线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:
先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。
可能你也许会问:为什么要搞得这么麻烦,如果每当客户端有新的请求时,我就创建一个新的线程不就完了?这也许是个不错的方法,因为它能使得你编写代码相对容易一些,但你却忽略了一个重要的问题??性能!
一个省级数据大集中的银行网络中心,高峰期每秒的客户端请求并发数超过100,如果为每个客户端请求创建一个新线程的话,那耗费的CPU时间和内存将是惊人的,如果采用一个拥有200个线程的线程池,那将会节约大量的的系统资源,使得更多的CPU时间和内存用来处理实际的商业应用,而不是频繁的线程创建与销毁。
那么他们是怎么来的?
我们通过JDK去操作线程( 代码 )---> JVM OS操作系统 ---> 操作系统底层的资源对象(线程)
2.分析线程池内部设计的原理
/*
* corePoolSize : 核心线程池数量,默认的线程池数量,创建线程池的时候,并没有马上创建CorePoolSize数量的线程对象
* 等到有任务进来的时候就创建这个corePoolSize量的线程放在线程池内部。
* 可以理解懒加载(线程的资源都是宝贵的,一旦创建出来就占用CPU资源内容资源,JVM创建一个线程的时候,复合栈大小初始化就有0.5MB)
* 一个操作系统上千个到万个线程(32位64位操作系统限制)
* */
/*
*
* KeepAliveTime: 表示我们的线程没有任务 执行的空闲状态 最大的存活时间。
* 细节(corePoolSize有关) 线程池中的整个线程数量都是少于corePoolSize。
* 那么KeepAliveTime就是无效的。
* 根据池化技术就是一种有备无患的思想: corePoolSize定的比较小,占用资源也比较小,万一高峰期来的时候,我们也不至于临时创建,简单的消峰
* maximumPoolSize:最大线程池里面装的线程对象的数量
* TimeUnit : 定时任务的时候TimeUnit解析我们的时间单位
* BlockingQueue :阻塞队列 用来在线程池当中都处于繁忙,存放在这个阻塞队列中 (FIFO)先进先出等等...
* RejectedExecutionHandler: 饱和策略的处理对象 */