> 之前学习线程池记录的笔记,现在放到这,顺便复习一下~
### 一、使用线程池的好处:
1. 降低资源的消耗。重复使用已创建的线程降低线程创建和销毁时的资源消耗
2. 提高响应速度。任务不需要等待线程创建就可以立即执行
3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一管理分配、调优和监控。

ThreadPoolExecutor执行execute() 的情况:
- (1)当corepool线程数小于corePoolSize时,创建新线程执行任务(需要获取全局锁)
- (2)当corepool线程数大于或等于corePoolSize时,将任务加到BlockingQueue中
- (3)当任务无法加到BlockingQueue(队列已满)时,创建新的线程执行任务
- (4)当创建新线程使当前线程数大于maxinumPoolSize时,任务将被拒绝,并且调用RejectExecutionHandler.rejectExecution
### 二、如何创建线程池及需要创建线程池需要输入的参数
详细的参数可以看源码
```
new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
}
new ThreadPoolExecutor (corePoolSize, maximumPoolSize, keepAliveTime,
milliseconds,runnableTaskQueue, handler);
```
创建线程池需要输入的参数:
1. corePoolSize(核心线程数):当提交一个任务到线程池时,线程池会创建一个线程,当当前线程数小于corePoolSize时,即使当前线程池有空闲线程,也会创建新的线程,直到需要执行的线程大于corePoolSize则不再创建。
2. workQueue(任务队列、阻塞队列):当线程池的线程时大于核心线程数时,任务则加到阻塞队列中去,任务在队列中等待。
常用的队列有:
- (1)ArrayBlockingQueue:基于数组结构的有界阻塞队列,按照FIFO(先进先出)的原则对元素进行排序,最大值为 Integer.MAX_VALUE
- (2)LinkedBlockingQueue:基于链表结构的有界阻塞队列,按照FIFO原则排序元素,吞吐量通常高于ArrayBlockingQueue,最大值为 Integer.MAX_VALUE
- (3)SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等待另一个线程调用移除操作,否则插入操作一直处于阻塞状态。吞吐量一般高于LinkedBlockingQueue。
- (4)PriorityBlockingQueue:一个具有优先级的无界阻塞队列
3. maninumPoolSize(线程池最大线程数):线程池允许创建的最大线程数。当队列已满且当前线程数小于最大线程数,线程池会创建新的线程执行任务。如果队列属于无界队列,则无效。
4. keepAliveTime(线程活动保持时间、存活时间):当线程池的工作线程空闲后,线程的存活时间。
5. unit(存活时间的单位):可选的单位有天(DAY)、小时(HOURS)、分钟(MINUTES)、秒(SECONDS)、毫秒(MILLISECONDS)、微秒(MICROSECONDS)
6. threadFactory(线程工厂):用于创建线程的工厂
7. RejectedExecutionHandler(饱和策略):当队列和线程池都满了,表示当前线程池处于饱和状态,需要采用一种策略来处理新提交的任务。
通常有以下几种策略:
- (1)ThreadPoolExecutor.AbortPolicy(默认):丢弃任务,并跑抛出异常
-(2)ThreadPoolExecutor.DiscardPolicy:不处理,直接丢弃,不抛出异常
-(3)ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列里最前面的任务,并执行当前任务
-(4)ThreadPoolExecutor.callerRunsPolicy:由调用线程处理该任务
### 三、向线程池提交任务
可以使用两个方法向线程池提交任务,execute()和 submit()
- (1)execute():用于提交不需要返回值的任务,无法判断任务是否被线程池执行成功
- (2)submit():用于提交需要返回值的任务

### 四、关闭线程池
可以调用线程池的shutdown 或 shutdownNow 方法来关闭线程池


Java中的线程池