面试--线程池的执行流程和拒绝策略有哪些?

一. 执行流程

聊到线程池就一定会聊到线程池的执行流程, 也就是当有一个任务进入线程池之后, 线程池是如何执行的?

想要真正的了解线程池的执行流程,就得先从线程池的执行方法 execute() 说起, execute() 实现源码如下: 

public void execute(Runnable command) {
    if (command == null) {
        throw new NullPointerException();
    }

    int c = ctl.get();

    // 当前工作的线程数小于核心线程数
    if (workerCountOf(c) < corePoolSize) {
        // 创建新的线程执行此任务
        if (addWorker(command, true)) {
            return;
        }
        c = ctl.get();
    }
    // 检查线程池是否处于运行状态,如果是则把任务添加到队列
    if (isRunning(c) && workQueue.offer(command)) {
        int recheck = ctl.get();

        // 再次检线程池是否处于运行状态,防止在第一次校验通过后线程池关闭
        // 如果是非运行状态,则将刚加入队列的任务移除
        if (! isRunning(recheck) && remove(command)) {
            reject(command);
        }

        // 如果线程池的线程数为 0 时(当 corePoolSize 设置为 0 时会发生)
        else if (workerCountOf(recheck) == 0) {
            addWorker(null, false); // 新建线程执行任务
        }
    }
    // 核心线程都在忙且队列都已爆满,尝试新启动一个线程执行失败
    else if (!addWorker(command, false)) {
        // 执行拒绝策略 
        reject(command);
    }
}

线程池的工作流程

总结

线程池的执行流程有 3 个重要的判断点:

  1. 判断当前线程数和核心线程数.
  2. 判断当前任务队列是否已满.
  3. 判断当前线程数是否已达最大线程数.

如果在经过上诉三个过程后, 得到的结果都是 true , 那么就会执行线程池的拒绝策略.

二. 拒绝策略

当任务过多且线程池的任务队列已满时, 此时就会执行线程池的拒绝策略, 线程池的拒绝策略默认有以下 4 种: 

  1. AbortPolicy:中止策略,线程池会抛出异常并中止执行此任务.
  2. CallerRunsPolicy:把任务交给添加此任务的(main)线程来执行.
  3. DiscardPolicy:忽略此任务,忽略最新的一个任务.
  4. DiscardOldestPolicy:忽略最早的任务,最先加入队列的任务.

在分析JDK自带的线程池拒绝策略前,先看下JDK定义的 拒绝策略接口:

public interface RejectedExecutionHandler {	
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);	
}

接口定义大概就是, 当触发拒绝策略时, 线程池会根据你设置的具体的策略, 将当前提交的任务以及线程池实例本身传递给你处理, 具体作何处理, 不同场景会有不同的考虑.

1. AbortPolicy(中止策略)

功能: 当触发拒绝策略时,直接抛出拒绝执行的异常,中止策略的意思也就是打断当前执行流程

2. CallerRunsPolicy(调用者运行策略)

功能:当触发拒绝策略时,只要线程池没有关闭,就由提交任务的当前线程处理.

3. DiscardPolicy(丢弃策略)

功能:直接静悄悄的丢弃这个任务,不触发任何动作.

4. DiscardOldestPolicy(弃老策略)

功能:如果线程池未关闭,就弹出队列头部的元素,然后尝试执行.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

即将秃头的菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值