参考文章:
https://www.jianshu.com/p/f5ead62827d7
作者:AKyS佐毅
链接:https://www.jianshu.com/p/f5ead62827d7
来源:简书
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2(节省创建/销毁的时间),则可以采用线程池,以提高服务器性能。另外发挥多核CPU的优势。
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率
java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池
ExecutorService pool = Executors.newFixedThreadPool(6);
一个线程池包括以下四个基本组成部分:
- 1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
- 2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
- 3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
- 4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
主要特点:
- 线程复用
- 控制最大并发数量
- 管理线程
继承关系:
创建线程池:
创建线程池的代码:
关键参数代码的意义:对于
newFixedThreadPool/newSingleThreadExecutor中,corePoolSize == maximumPoolSize;
newCachedThreadPool中,maximumPoolSize = Inter.MAX_VALUE.
如果上述Pool不能满足需求,可以在自己的代码中直接调用ThreadPoolExecuto
keepAliveTime默认是0;
WorkQueue: 阻塞队列,放临时任务。
线程池的处理流程:
4、四种拒绝策略
- ThreadPoolExecutor.AbortPolicy():抛出java.util.concurrent.RejectedExecutionException异常
- ThreadPoolExecutor.CallerRunsPolicy: 用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
- ThreadPoolExecutor.DiscardOldestPolicy():该策略将丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
- ThreadPoolExecutor.DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。