一、前言
java中实现线程有以下三种方式:
- 实现Runnable接口
- 继承Thread类
- 实现Callable接口
如果请求非常多,就会频繁的创建和销毁线程,如此一来会大大降低系统的效率。因此,线程池就随之产生了。
二、Executor 线程池
1.线程池5种状态
- RUNNING:能够接收新任务,以及对已添加的任务进行处理
- SHUTDOWN:不接收新任务,但能处理已添加的任务
- STOP:不接收新任务,不处理已添加的任务,并且会中断正在处理的任务
- TIDYING:所有的任务已终止,任务数量为0
- TERMINATED:线程池处在TIDYING状态时,执行完terminated()之后,线程池彻底终止
三、ThreadPoolExecutor线程池
ThreadPoolExecutor 是 Executor 的默认实现。
1.参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
①.corePoolSize
核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当 前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到 阻塞队列中,等待被执行
②.maximumPoolSize
最大线程数,如果当前阻塞队列满了,且继续提交任务,则创建新的线 程执行任务
③.keepAliveTime
维护线程所允许的空闲时间,当线程池中的线程数量大于corePoolSize的时 候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待 的时间超过了keepAliveTime;
④.unit
时间单位
⑤.workQueue
阻塞队列,有以下几种类型:
- ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务;
- LinkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞 吐量通常要高于ArrayBlockingQuene;
- SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到 另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于 LinkedBlockingQuene;
- priorityBlockingQuene:具有优先级的无界阻塞队列;
⑥.threadFactory
默认使用 Executors.defaultThreadFactory() 来创建线程
⑦.handler 饱和策略
饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必 须采取一种策略处理该任务,线程池提供了4种策略:
- AbortPolicy:默认策略,直接抛出异常;
- CallerRunsPolicy:当前线程执行任务;
- DiscardOldestPolicy:丢弃阻塞队列中最前的任务,并执行当前任务;
- DiscardPolicy:直接丢弃任务;
你也可以自定义饱和策略,只需要实现RejectedExecutionHandler接口
2.执行过程
如图:
四、总结
以上属于个人理解,有错误望指正。