- 线程池基础使用
- 一、核心组件和核心类
- 二、线程池的工作流程
- 三、线程池的拒绝策略
- 四、6种常用的线程池
- 五、线程池的使用
- 线程池的创建
- 向线程池提交任务
- 关闭线程池
- ThreadPoolExecutorDemo示例
- 六、线程池的好处
4个核心组件
- 线程池管理器 用于创建和管理线程
- 工作线程 线程池中执行具体任务的线程
- 任务接口 用户定义工作线程的调度和执行策略,只有线程实现了该接口,线程的任务才能够被线程池调度。
- 任务队列 存放待处理的任务,新的任务加入队列,执行完成的任务会被队列移除。
java中的线程池通过Executor框架实现的核心类如下:
Executor、Executors 、ExecutorService、ThreadPoolExcutor、Callable、Future、 FutureTask
创建线程池的核心类ThreadPoolExcutor的核心方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
...
}
参数说明
-
corePoolSize:线程池中的核心线程数量
-
maximumPoolSize:线程池中最大线程数量
-
keepAliveTime:当线程数超过corePoolSize时,线程空闲存活时长
-
unit:的时间单位
-
workQueue:任务队列,被提交但是尚未执行的任务的存放处
-
threadFactory:线程工厂,用户创建线程,一般默认
-
handler:拒绝策略,任务过多或者其他原因导致线程池无法处理任务的拒绝策略。
核心线程池和非核心线程池
核心线程不会被销毁 而非核心线在空闲后超过keepaliveTime之后会被销毁。
三、线程池的拒绝策略当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略。JDK内置的拒绝策略有4种。
ThreadPoolExecutor.AbortPolicy //默认,丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy //丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy //尝试丢弃队列最前面的任务,然后重新提交被当前的任务
ThreadPoolExecutor.CallerRunsPolicy //由调用线程(提交任务的线程)处理该任务 如果调用线程未关闭的话
自定义拒绝策略
以上的拒绝策略都实现了RejectedExecutionHandler接口,说明可以自己通过实现RejectedExecutionHandler来编写自己的拒绝策略。
四、6种常用的线程池- newCachedThreadPool 缓存线程池
在创建新线程时,如果有空闲的线程就重用它们。 使用场景在执行时间短的大量任务是可以使用。
- newFixedThreadPool
创建一个固定线程数的线程池,并形成队列循环使用。
- newScheduledThreadPool
可定时调度的线程池,在延迟时间后执行或者定期执行某个线程任务。
- newSingleThreadExecutor
线程池中只有1个线程执行任务,在该线程出现停止或异常时,会启动一个新的线程进行工作。
- newSingleScheduleThreadPool
此线程有点结合的意思,是一个只有一个线程的线程池,可用定时任务。
- newWorkStealingPool
创建一个具有抢占式操作的线程池,stealing 翻译为抢断、窃取的意思,它实现的一个线程池和上面4种都不一样,用的是 ForkJoinPool 类。它是一个并行的线程池,参数中传入的是一个线程并发的数量,这里和之前就有很明显的区别,前面4种线程池都有核心线程数、最大线程数等等,而这就使用了一个并发线程数解决问题。从介绍中,还说明这个线程池不会保证任务的顺序执行,也就是 WorkStealing 的意思,抢占式的工作。
五、线程池的使用 线程池的创建 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5,
10,
3,
TimeUnit.SECONDS,
new ArrayBlockingQueue(3),
new ThreadPoolExecutor.AbortPolicy());
向线程池提交任务
threadPoolExecutor.execute(new WorkTask(task));
关闭线程池
threadPoolExecutor.shutdown();
ThreadPoolExecutorDemo示例
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorDemo {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5,
10,
3,
TimeUnit.SECONDS,
new ArrayBlockingQueue(3),
new ThreadPoolExecutor.AbortPolicy());
for (int i = 1; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?