ThreadPoolExecutor线程池源码分析与流程图

使用线程池

//创建线程池
ThreadPoolExecutor test = new ThreadPoolExecutor(1, 1, 5000, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), ThreadPoolExecutor.defaultHandler);
//添加任务
test.submit(() -> {
   System.out.println(1);
});

参数详解:

  1. corePoolSize:核心线程数,添加任务时,如果线程数没有达到这个数量,创建新的线程
  2. maximumPoolSize:总线程数,当核心线程与阻塞队列满了以后,线程的数量没有超过这个值,创建新线程
  3. keepAliveTime:非核心线程会等到这个时间后,销毁
  4. unit:时间单位
  5. workQueue:核心线程满了以后,放入的队列
    • ArrayBlockingQueue:基于数组的阻塞队列
    • LinkedBlockingQuene:基于链表的阻塞队列
    • SynchronousQuene:不存元素,直接阻塞的队列
    • PriorityBlockingQuene:具有优先级阻塞队列
  6. threadFactory:创建线程的工场
  7. handler:饱和策略
    • AbortPolicy:直接抛出异常(默认策略)
    • CallerRunsPolicy:调用者所在线程执行任务
    • DiscardOldestPolicy:丢弃阻塞队列中最前任务
    • DiscardPolicy:直接丢弃
    • …自定义

线程池原理:

添加线程时,优先创建核心线程,当核心线程数满了以后,放入阻塞队列中,当阻塞队列满了以后创建非核心线程,核心线程中的任务执行完以后,从阻塞队列中获取
在这里插入图片描述

执行流程图:

在这里插入图片描述

源码分析

submit

public Future<?> submit(Runnable task) {
     if (task == null) {
         throw new NullPointerException();
     }
     // 包装类
     RunnableFuture<Void> ftask = newTaskFor(task, null);
     // 执行
     execute(ftask);
     return ftask;
 }

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();
    }
    // 如果线程池正在运行,将任务放入BlockingQueue队列中
    if (isRunning(c) && workQueue.offer(command)) {
        // 如果放入队列成功
        int recheck = ctl.get();
        if (!isRunning(recheck) && remove(command)) {
            // 如果线程池结束了,执行饱和策略
            reject(command);
        } else if (workerCountOf(recheck) == 0) {
            addWorker(null, false);
        }
    } else if (!addWorker(command, false)) {
        // 队列满了,并且添加非工作线程失败,进入饱和策略
        reject(command);
    }
}

addWorker

private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    // 自旋
    for (;;) {
        int c = ctl.get();
        // 判断线程池状态
        int rs = runStateOf(c);
        // 如果线程池停止,直接返回false
        if (rs >= SHUTDOWN && !(rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty())) {
            return false;
        }
        // 自旋+cas添加线程,直到添加成功或者不符合添加的条件
        for (;;) {
            // 获取工作线程个数
            int wc = workerCountOf(c);
            // 判断当前工作的线程是否大于等于线程池最大工作数
            // 如果添加的是核心线程,判断工作的线程数是否超过核心线程数量
            // 如果是非核心线程,判断工作的线程数是否超过总工作线程数
            // 满足上面条件,直接返回false
            if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) {
                return false;
            }
            // 修改核心线程数量,跳出全部循环
            if (compareAndIncrementWorkerCount(c)) {
                break retry;
            }

            c = ctl.get();
            // 如果状态有变化,跳出此层循环
            if (runStateOf(c) != rs) {
                continue retry;
            }
        }
    }

    boolean workerStarted = false;
    boolean workerAdded = false;
    Worker w = null;
    try {
        // 包装成worker(继承AQS),并用线程工场类创建线程出来
        // 设置此线程第一个工作任务
        w = new Worker(firstTask);
        final Thread t = w.thread;
        if (t != null) {
            // 加锁
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // 获取线程池状态
                int rs = runStateOf(ctl.get());
                if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive()) {
                        throw new IllegalThreadStateException();
                    }
                    // 添加到任务队列中
                    workers.add(w);
                    int s = workers.size();
                    if (s > largestPoolSize) {
                        largestPoolSize = s;
                    }
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                // 如果工作线程添加成功,启动线程
                t.start();
                workerStarted = true;
            }
        }
    } finally {
        if (!workerStarted) {
            addWorkerFailed(w);
        }
    }
    return workerStarted;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值