一、为什么要用线程池
- 降低资源消耗 。通过重复利用已创建的线程降低线程创建、销毁线程造成的消耗 。
- 提高响应速度 。当任务到达时 , 任务可以不需要等到线程创建就能立即执行 。
- 提高线程的可管理性 。线程是稀缺资源 , 如果无限制的创建 , 不仅会消耗系统资源 , 还会降低系统的稳定性 , 使用线程池可以进行统一的分配、调优和监控 。

文章插图
当线程池任务处理不过来的时候(什么时候认为处理不过来后面描述) , 可以通过handler指定的策略进行处理 , ThreadPoolExecutor提供了四种策略:
- ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常;也是默认的处理方式 。
- ThreadPoolExecutor.DiscardPolicy:丢弃任务 , 但是不抛出异常 。
- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务 , 然后重新尝试执行任务(重复此过程)
- ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
三、线程池任务执行

文章插图
1. 添加执行任务
- submit() 该方法返回一个Future对象 , 可执行带返回值的线程;或者执行想随时可以取消的线程 。Future对象的get()方法获取返回值 。Future对象的cancel(true/false)取消任务 , 未开始或已完成返回false , 参数表示是否中断执行中的线程 。
- execute() 没有返回值 。

文章插图
2.1. 如果此时线程池中的数量小于corePoolSize , 即使线程池中的线程都处于空闲状态 , 也要创建新的线程来处理被添加的任务 。
2.2. 如果此时线程池中的数量等于corePoolSize , 但是缓冲队列workQueue未满 , 那么任务被放入缓冲队列 。
2.3. 如果此时线程池中的数量大于等于corePoolSize , 缓冲队列workQueue满 , 并且线程池中的数量小于maximumPoolSize , 建新的线程来处理被添加的任务 。
2.4. 如果此时线程池中的数量大于corePoolSize , 缓冲队列workQueue满 , 并且线程池中的数量等于maximumPoolSize , 那么通过 handler所指定的策略来处理此任务 。
2.5. 当线程池中的线程数量大于 corePoolSize时 , 如果某线程空闲时间超过keepAliveTime , 线程将被终止 。这样 , 线程池可以动态的调整池中的线程数 。
总结:处理任务判断的优先级为 核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize , 如果三者都满了 , 使用handler处理被拒绝的任务 。
注意:
- 当workQueue使用的是×××限队列时 , maximumPoolSize参数就变的无意义了 , 比如new LinkedBlockingQueue(),或者new ArrayBlockingQueue(Integer.MAX_VALUE);
- 使用SynchronousQueue队列时由于该队列没有容量的特性 , 所以不会对任务进行排队 , 如果线程池中没有空闲线程 , 会立即创建一个新线程来接收这个任务 。maximumPoolSize要设置大一点 。
- 核心线程和最大线程数量相等时keepAliveTime无作用.
3.1. shutdown() 不接收新任务,会处理已添加任务
3.2. shutdownNow() 不接受新任务,不处理已添加任务,中断正在处理的任务
4. 常用队列介绍
4.1. ArrayBlockingQueue: 这是一个由数组实现的容量固定的有界阻塞队列.
4.2. SynchronousQueue: 没有容量 , 不能缓存数据;每个put必须等待一个take; offer()的时候如果没有另一个线程在poll()或者take()的话返回false 。
4.3. LinkedBlockingQueue: 这是一个由单链表实现的默认×××的阻塞队列 。LinkedBlockingQueue提供了一个可选有界的构造函数 , 而在未指明容量时 , 容量默认为Integer.MAX_VALUE 。
队列操作:

文章插图
5. Executors线程工厂类
1. Executors.newCachedThreadPool();
说明: 创建一个可缓存线程池 , 如果线程池长度超过处理需要 , 可灵活回收空闲线程 , 若无可回收 , 则新建线程.
推荐阅读
- 梦见池塘的水干了里面有好多鱼是什么意思 梦见池塘的水干了,但是能看见鱼
- 梦见水从地下往上冒成了一个池塘 梦见水从地下往上冒,地裂缝
- 梦见自己掉粪池里了,又爬出来了 梦见掉粪池里又爬出来然而身上好多蛆
- 2020年的九大热门 Java 框架
- 你知道这高效的12个Java精品库嘛?
- JavaScript如何实现字符串拼接操作
- Java 代码执行原理
- Java几种常用的断言风格你怎么选?
- 如何确定线程池的大小?
- 要精通Java,先研究Java的执行原理
