Java线程池
一.为什么使用线程池?
- 降低资源的消耗。通过重复利用已创建线程降低线程创建,销毁线程造成的消耗;
- 提高效应速度。当任务到达时,任务可以不需要等待线程的创建就能立即执行;
- 提高线程的可管理性。线程是稀缺资源,如果无限的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控。
二. Java提供的线程池
Java提供五种线程池,如下所示:
| Executors线程类工程 | 说明 |
| newCachedThreadPool() | 创建可缓存线程池,系统根据需要创建线程池,这些线程将缓存到线程池中。 |
| newFixedThreadPool() |
创建一个可重用的、具有固定线程数的线程池。 |
| newSingleThreadExecutor() | 创建一个只有单线程的线程池,它相当于调用newFixedThreadPool(1),保证所有的任务都是按照顺序执行。 |
| newScheduledThreadPool() | 创建指定的线程数的线程池,它可以在制定延迟后执行任务。corePoolSize 指池中 |
| newSingleThreadScheduleExecutor() | 创建只有一个线程的线程池,,它可以在指定延迟后执行线程任务。 |
三.ThreadPoolExecutor线程池参数详解
| 参数名称 | 说明 |
| corePoolSize | 核心线程数量,线程池维护线程最少数量 |
| maxinumPoolSize | 线程池维护线程的最大数量 |
| KeepAliveTime | 线程池除了核心线程外的其他线程的最长的空闲时间,超过该时间的空闲线程会被销毁 |
| unit | keepAliaveTime的单位,TimeUnit中的几个静态属性:NANOSECODES MICROSECONDS MILLSECONDS SECONDS |
| workQueue | 线程池所使用的任务缓冲队列 |
| threadFactory | 线程工厂,用于创建线程,一般用默认的即可 |
| handler | 线程池拒绝任务的处理策略 |
四.线程池的执行
- 添加执行任务
- submit() 该方法返回一个Future对象,可执行带返回值的线程;或者执行想随时可以取消的线程。Future 对象的get()方法获取返回值。 Future 对象的cancel(true/false)取消任务,未开始或已完成返回false,参数表示是否中断执行中的线程。
- execute()没有返回值。
2.线程池任务的提交过程
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处理被拒绝的任务;
3.handler:ThreadPoolExecutor的提供的四种处理策略
| 名称 | 说明 |
| ThreadPoolExecutor.AbortPolicy | 丢弃任务并抛出RejectedException异常;也是默认的处理方式。 |
| ThreadPoolExecutor.DiscardPolicy | 丢弃任务,但是不抛出异常 |
| ThreadPoolExecutor.DiscardOldestPolicy | 丢弃队列最前面的任务,然后重新尝试执行 |
| ThreadPoolExecutor.CallerRunsPolicy | 由调用的线程处理该任务。 |
4.线程池的关闭
4.1.shutdown()不接收新任务,会处理已添加的任务
4.2.shutdownNow()不接收新任务,不执行已添加任务,中断正在处理的任务。
5.常用的队列
- ArrayBlockingQueue:由数组现实的容量固定的有界限阻塞队列;
- SychronousQueue:没有容量,不能缓存数据;每个put必须等待一个take;offer()的时候如果没有另一个线程在poll()或者take()的话返回false;
- LinkedBlockingQueue:由单链表实现的默认不限容量的阻塞队列。LinkedBlockingQueue提供了一个可选有界的构造函数,而在未指明容量时,容量默认时Integer.MAX_VALUE 。
五.Java提供Executors线程工厂类
Java提供Exceutors类来创建线程池
- Exceutors.newCachedThreadPool()
- Exceutors.newFixedThreadPool()
- Exceutors.newSingleThreadExecutor()
- Exceutors.newScheduledThreadPool()
- Exceutors.newSingleThreadScheduleExecutor()
170万+

被折叠的 条评论
为什么被折叠?



