Java线程池

一、Java工具类创建线程

通过Executors工具类进行快速创建线程池:
1.newFixedThreadPool ——固定线程数
2.newCachedThreadPool——具有缓存功能
3.newSingleThreadExecutor——单一线程池
4.newScheduledThreadPool——周期性线程池

但是以上几种都不推荐使用,原因如下:

  1. FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
  2. CachedThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

建议使用自定义线程池,这样可以更加理解线程池的运行方式,以及对资源的把控度。

// 自定义线程池
// int corePoolSize= 核心线程数
// int maximumPoolSize = 最大线程数
// long keepAliveTime = 线程存活时间
// TimeUnit unit = 时间单位                         
// BlockingQueue workQueue = 工作队列
// ThreadFactory threadFactory = 创建线程的工厂
// RejectedExecutionHandler handler = 拒绝策略
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 1, TimeUnit.MINUTES,
        new LinkedBlockingQueue<>(10));

二、线程池的生命周期

线程池状态转换

1.RUNNING:线程池创建后的初始状态,可以提交新任务,可以处理工作队列中的任务。
2.SHUTDOWN:线程池关闭状态,不再接受新的任务,但是仍然可以处理工作队列中的任务。
3.STOP:不接受新任务,不处理排队任务,中断进行中的任务。
4.TIDYING:所有任务都已终止,workerCount 为零,TIDYING是过渡状态将运行 terminated() 方法。
5.TERMINATED:terminated() 方法已经执行完毕,线程池已关闭。

三、拒绝策略

拒绝策略

1.AbortPolicy:抛出RejectedExecutionException异常,拒绝提交任务,是线程池默认拒绝策略。
2.CallerRunsPolicy:由调用execute()方法的线程进行执行这个任务,如果这个线程无法执行,任务将丢弃。
3.DiscardOldestPolicy:丢弃队列头结点任务,然后再去执行当前任务。
4.DiscardPolicy:啥都不做,丢弃任务。

四、整体执行流程图

整体执行流程

1.有任务提交过来,先分配给核心线程执行
2.核心线程满了之后,将后续任务提交到工作队列中
3.工作队列也存放满了,就看最大线程数有没有满,没有就继续增加线程
4.最大线程数也满了,就会执行拒绝策略,默认是AbortPolicy

五、源码剖析

ThreadPoolExecutor类重点信息:

public class ThreadPoolExecutor extends AbstractExecutorService {
    // ctl由线程数和线程池的状态两部分组成
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    // 29位代表线程数量  高3位代表线程池的状态
    private static final int COUNT_BITS = Integer.SIZE - 3;
    // 线程池最大容量
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    
    // 接受新任务并处理排队的任务
    private static final int RUNNING    = -1 << COUNT_BITS;
    // 不接受新任务,但处理排队的任务
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    // 不接受新任务,不处理排队任务,中断进行中的任务
    private static final int STOP       =  1 << COUNT_BITS;
    // 所有任务都已终止,workerCount为零,TIDYING是过渡状态,将运行terminated()方法
    private static final int TIDYING    =  2 << COUNT_BITS;
    // terminated()方法已经执行完毕,线程池已经终止
    private static final int TERMINATED =  3 << COUNT_BITS;
    
    // 获取线程池运行状态
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    // 获取线程个数
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    // 位或运算 "0 | 1 = 1; 0 | 0 = 0;" 获取ctl的值
    private static int ctlOf(int rs, int wc) { return rs | wc; }
    // ...省略其它方法
}

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(); // 再次获取ctl的值,用于二次检查
        // 当前线程池状态不是运行中,就会移除刚刚添加的任务
        if (! isRunning(recheck) && remove(command))
            // 调用拒绝策略
            reject(command);
        else if (workerCountOf(recheck) == 0)// 当前线程池线程数量== 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); // 线程池运行状态

        // rs >= SHUTDOWN  当前线程池状态不是运行中
        // case1:SHUTDOWN,不接受新任务
        // case2:当队列为空,那么也就没必要创建worker
        if (rs >= SHUTDOWN && 
            ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())
            )
            return false;

        for (;;) {
            int wc = workerCountOf(c); // 线程个数
            // 超出线程数 线程数>= 线程池阈值 || 线程数 >= (核心线程数 || 最大线程数)
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
            if (compareAndIncrementWorkerCount(c)) // cas操作,线程数+1,跳出循环
                break retry;
            c = ctl.get();  // 再次获取ctl的值
            if (runStateOf(c) != rs) //如果两次的状态不相等,就跳过本次循环
                continue retry;
            // else CAS failed due to workerCount change; retry inner loop
        }
    }

    boolean workerStarted = false; // worker线程是否已开启
    boolean workerAdded = false; // worker是否已经添加
    Worker w = null;
    try {
        w = new Worker(firstTask); // 这里是创建线程、绑定任务
        final Thread t = w.thread;
        if (t != null) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // Recheck while holding lock.
                // Back out on ThreadFactory failure or if
                // shut down before lock acquired.
                int rs = runStateOf(ctl.get()); // 获取线程池状态
                
                // 如果线程池状态为Running 或者 线程池状态为shutdown但是没有任务
                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive()) // 检查线程是否处于存活状态,如果是就说明线程出现异常
                        throw new IllegalThreadStateException();
                    workers.add(w); // 添加到HashSet集合中,并且是持有锁的
                    int s = workers.size();
                    if (s > largestPoolSize) // 跟踪最大的池大小。只能在 mainLock 下访问。
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                t.start(); // 启动线程
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted) // 线程启动失败
            addWorkerFailed(w); // 回滚工作线程创建。线程数-1,重新检查是否终止,以防该 worker没有终止
    }
    return workerStarted;
}

addWorkerFailed():

private void addWorkerFailed(Worker w) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        if (w != null)
            workers.remove(w); // 从worker集合中移除
        decrementWorkerCount(); // 线程数 -1
        tryTerminate(); // 终止当前线程运行
    } finally {
        mainLock.unlock();
    }
}

tryTerminate():

final void tryTerminate() {
    for (;;) {
        // 获取ctl的值
        int c = ctl.get();
        // 当前线程池的状态为running
        // 当前线程池状态 为tidying 或 terminated
        // 当前线程池状态为shutdown 同时 队列不为空
        if (isRunning(c) ||
            runStateAtLeast(c, TIDYING) ||
            (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
            return;
        if (workerCountOf(c) != 0) { // 线程的个数不等于0,就中断一个等待的线程
            interruptIdleWorkers(ONLY_ONE);
            return;
        }

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 修改线程池的状态为tidying
            if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                try {
                    // Executor 终止时调用的方法。默认实现什么也不做。
                    terminated();
                } finally {
                    // 修改线程池状态为terminated
                    ctl.set(ctlOf(TERMINATED, 0));
                    // 唤醒等待线程
                    termination.signalAll();
                }
                return;
            }
        } finally {
            mainLock.unlock();
        }
        // else retry on failed CAS
    }
}

在剖析后面的源码前,必须要了解Worker这个类的相关重点信息。
Worker类:

private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
    // 当前Worker绑定的线程
    final Thread thread;
    // 创建worker时绑定的第一个初始任务
    Runnable firstTask;
    // 当前worker累计完成的任务数量
    volatile long completedTasks;

    /**
     * Creates with given first task and thread from ThreadFactory.
     * @param firstTask the first task (null if none)
     */
    Worker(Runnable firstTask) {
        // 初始化时,不能抢占AQS的独占锁
        setState(-1); // inhibit interrupts until runWorker
        this.firstTask = firstTask; // 绑定初始任务
        this.thread = getThreadFactory().newThread(this); // 创建线程并绑定
    }

    // 启动线程后,真正执行任务的方法
    /** Delegates main run loop to outer runWorker  */
    public void run() {
        runWorker(this);
    }
    // ...省略部分方法
}

runWorker():

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread(); // 获取绑定的实例
    Runnable task = w.firstTask; // 获取要执行的任务
    w.firstTask = null;
    w.unlock(); // allow interrupts // 将state的值进行复原
    boolean completedAbruptly = true;
    try {
        // 如果task为空,就从队列去获取任务,否则就直接执行
        while (task != null || (task = getTask()) != null) {
            w.lock();
            // If pool is stopping, ensure thread is interrupted;
            // if not, ensure thread is not interrupted.  This
            // requires a recheck in second case to deal with
            // shutdownNow race while clearing interrupt
            
            // 条件一:runStateAtLeast(ctl.get(), STOP)  说明线程池目前处于STOP/TIDYING/TERMINATION 此时线程一定要给它一个中断信号
            // 条件二:Thread.interrupted() && runStateAtLeast(ctl.get(), STOP),根据条件一的状态,增加中断标志位的判断
            // 条件三:!wt.isInterrupted() 只要没有设置中断标志,都会进入并设置
            if ( (runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP)) ) &&
                !wt.isInterrupted())
                wt.interrupt(); // 设置中断标志
            try {
                beforeExecute(wt, task); // 前置执行,默认空实现
                Throwable thrown = null;
                try {
                    task.run(); // 真正执行业务的地方
                } catch (RuntimeException x) {
                    thrown = x; throw x;
                } catch (Error x) {
                    thrown = x; throw x;
                } catch (Throwable x) {
                    thrown = x; throw new Error(x);
                } finally {
                    afterExecute(task, thrown); // 后置执行
                }
            } finally {
                task = null;
                w.completedTasks++; //任务执行完毕,进行累加
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

getTask():

private Runnable getTask() {
    // 出队操作是否超时了
    boolean timedOut = false; // Did the last poll() time out?

    for (;;) {
        // 获取ctl的值
        int c = ctl.get();
        int rs = runStateOf(c); // 获取线程池的状态

        // Check if queue empty only if necessary.
        // case1:rs >= SHUTDOWN 当前线程池状态 是 shutdown、stop、tidying、terminated
        // case2:当前线程池状态 是stop、tidying、terminated 或者 队列为空
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount(); //当前线程数-1
            return null;
        }

        int wc = workerCountOf(c); // 获取线程数

        // Are workers subject to culling?
        // allowCoreThreadTimeOut=true 核心线程数可以回收
        // allowCoreThreadTimeOut=false 核心线程数不会回收
        // wc > 核心线程数
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
        
        // 当前线程数>最大线程数 或者 (允许超时销毁 并且 上次出队操作超时)
        // 当前线程数大于1或者队列为空
        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c)) // 线程数-1
                return null;
            continue;
        }

        try {
            // timed =true 允许超时销毁,就使用带时间的poll出队
            // tiemd =false 不允许超时销毁,就使用take出队
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true; // 如果没有取出,就标识超时
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

processWorkerExit():

private void processWorkerExit(Worker w, boolean completedAbruptly) {
    // completedAbruptly=true 执行runWorker出现异常,线程数需要-1
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        decrementWorkerCount();

    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        completedTaskCount += w.completedTasks; // 当前worker累计完成数量进行累加
        workers.remove(w); // 从集合中移除当前worker
    } finally {
        mainLock.unlock();
    }

    tryTerminate(); // 终止线程 或终止线程池

    int c = ctl.get();
    // 如果是shutdown 、running
    if (runStateLessThan(c, STOP)) {
        if (!completedAbruptly) { // worker执行没有出现异常
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize; // 允许销毁核心线程
            if (min == 0 && ! workQueue.isEmpty()) // 如果当前没有线程了,但是队列还有任务,就保留一个线程
                min = 1;
            if (workerCountOf(c) >= min)
                return; // replacement not needed
        }
        addWorker(null, false); // 保留一个线程,去完成队列
    }
}

你可能感兴趣的:(Java线程池)