一、为什么要用线程池
在现实开发中是不会手动地去new一个线程出来用的,阿里巴巴的Java开发手册中也写到不要手动创建线程,要使用线程池。几乎所有的需要异步或者并发执行的程序都可以使用线程池。使用线程池有三个好处:
- 降低资源的消耗:在线程池中有一些已经创建好的线程,通过重复利用这些线程,可以减低线程的创建和销毁造成的消耗。
- 提高响应速度:当要执行的任务达到之后,不需要去创建线程池,可以立即执行。
- 提高线程的可管理性:线程是珍贵的资源,要是重量级的。不能无限制地去创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以统一管理、调优和监控线程。
二、线程池的处理流程
当提交一个新任务到线程池时,线程池的处理流程如下:
1、线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。
2、线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。 3、线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
如下图:
Java中线程池的类是ThreadPoolExecutor,里面执行的方法是execute方法,主要的execute的执行流程如下:
总得来说,ThreadPoolExecutor的execute方法大致的设计思路是这样的:
1、如果当前线程池运行的线程少于corePoolSize,那么就创建一个线程来执行提交过来的任务。(此操作需要获取全局锁)
2、如果当前线程池运行的线程等于或者大于corePoolSize,那么提交过来任务会被放置在BlockingQueue(阻塞队列)中。
3、如果BlockingQueue(阻塞队列)已满,那么就创建新的线程来处任务(此操作需要获取全局锁)
4、如果撞见新的线程之后,线程池中的线程数大于maximumPoolSize,提交过来的任务会被拒绝执行,并执行拒绝策略
三、execute方法源码解析
|
|