前言
在Java并发编程中,线程池是应用场景最多的一种并发框架,也是高频面试知识点之一。大部分并发执行任务都可以用到线程池。使用线程池有很多的好处,本文将对线程池进行详细的介绍。
使用线程池的好处
线程的可管理性
线程池统一管理,调度线程,控制池中的线程数量,线程池中的线程资源重复利用。
提高资源利用率
线程池帮忙管理线程,通过重复使用线程池中创建的线程,降低创建和销毁线程所造成的资源消耗
提高响应速度
有时候可以不需要等待线程创建,当核心线程数满了的时候,会把任务放到队列里,空闲线程会从里面拉去任务执行。
线程池的一些核心参数
在线程池初始化的时候,会传一些参数,用来配置线程池,下面来了解一下相关核心参数。
核心线程数(corePoolSize)
线程池会设置一个核心线程数,即最小线程数,这些线程即使空闲状态,也不会被销毁;当提交一个任务的时候,会先判断核心线程数满了没有,没有就创建,(即使这个时候有空闲线程也会创建新线程来处理该任务)。
阻塞队列
当提交一个任务,这个时候核心线程数已经满了,就会放到队列中,空闲的线程会从该队列拉取任务进行处理。
最大线程数
当核心线程数满了,队列也满了的时候就会判断配置的最大线程数满了没有,如果最大线程数没有满就创建线程。
keepAliveTime 等待工作的空闲线程的超时时间
TimeUnit 超时时间单位
拒绝策略(RejectedExecutionHandler)
当队列满了,最大线程数也满了,就会执行配置的拒绝策略。jdk中默认提供了四种拒绝策略。
CallerRunsPolicy
直接在execute方法的调用线程中运行被拒绝的任务,除非执行器已关闭,在这种情况下,该任务将被丢弃。
优点:1、任务不会被丢弃,不会丢数据。2、谁提交的任务给谁处理,减缓提交任务的速度,给线程池缓冲期,这段时间线程池又会执行掉一些任务,腾出一些队列空间。
缺点:让主线程执行任务,可能会造成主线程阻塞
AbortPolicy--默认拒绝策略
拒绝该任务,并且抛异常
优点:会抛异常,感知到异常之后,可以根据具体业务逻辑做相应的处理。
缺点:如果没有做相应的处理或者处理不好,也会造成任务丢失
DiscardPolicy
丢弃该任务,啥也不干
缺点:任务丢失,容易造成数据不完整
DiscardOldestPolicy
丢弃队列中最旧的未处理任务,再把当前任务放到队列
缺点:任务丢失,容易造成数据不完整
线程池核心线程会被销毁吗?
默认不会被销毁,但可以配置allowsCoreThreadTimeOut 参数为true使得核心线程空闲后也会被回收
/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
private volatile boolean allowCoreThreadTimeOut;