# ThreadPoolExecutor
# 构造方法
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- corePoolSize 核心线程数目 (最多保留的线程数)
- maximumPoolSize 最大线程数目
- keepAliveTime 生存时间 - 针对救急线程
- unit 时间单位 - 针对救急线程
- workQueue 阻塞队列
- threadFactory 线程工厂 - 可以为线程创建时起个好名字
- handler 拒绝策略
# 拒绝策略
JDK 提供了4中拒绝策略
- AbortPolicy(默认策略) 让调用者抛出 RejectedExecutionException 异常
- CallerRunsPolicy 让调用者运行任务
- DiscardPolicy 放弃本次任务
- DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
# 工作模式
- 线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务。
- 当线程数达到 corePoolSize 并没有线程空闲,这时再加入任务,新加的任务会被加入workQueue 队列排队,直到有空闲的线程。
- 如果队列选择了有界队列,那么任务超过了队列大小时,会创建 maximumPoolSize - corePoolSize 数目的线程来救急。
- 如果线程到达 maximumPoolSize 仍然有新任务这时会执行拒绝策略。拒绝策略 jdk 提供了 4 种实现
根据这个构造方法,JDK Executors 类中提供了众多工厂方法来创建各种用途的线程池
# 关闭线程池
# shutdown
线程池状态变为 SHUTDOWN,不会接收新任务,但已提交任务会执行完,此方法不会阻塞调用线程的执行
# shutdownNow
线程池状态变为 STOP,不会接收新任务,会将队列中的任务返回,并用 interrupt 的方式中断正在执行的任务
# 其它方法
isShutdown 不在 RUNNING 状态的线程池,此方法就返回 true
isTerminated 线程池状态是否是 TERMINATED
awaitTermination 调用 shutdown 后,由于调用线程并不会等待所有任务运行结束,因此如果它想在线程池 TERMINATED 后做些事情,可以利用此方法等待
# 异常处理
- try-catch
@Slf4j
public class ABA {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
pool.schedule(() -> log.info("start"), 1L, TimeUnit.SECONDS);
pool.schedule(() -> {
try {
int i = 5 / 0;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}, 1, TimeUnit.SECONDS);
}
}
- Future
@Slf4j
public class ABA {
public static void main(String[] args) throws Exception {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
pool.schedule(() -> log.info("start"), 1L, TimeUnit.SECONDS);
//schedule,也可以submit
ScheduledFuture<Boolean> future = pool.schedule(() -> {
int i = 5 / 0;
//这里的返回信息以实际业务为准
//如果不返回,会被当作runnable
return true;
}, 1, TimeUnit.SECONDS);
log.info("future:{}", future.get());
}
}