线程池

线程池中的非核心线程是怎么被回收的?

 

 

线程吃中的核心线程是怎么被回收的?

 

Runnable   Callable   Thread   Future

 

线程池中的所有的woker线程都放在一个  HashSet中。

    private final HashSet<Worker> workers = new HashSet<Worker>();

 

 线程池的生命周期:

  和线程的生命周期有什么联系?

线程池的生命周期:

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;      // 接收新的任务,并且执行队列中的任务
    private static final int SHUTDOWN   =  0 << COUNT_BITS;      // 不接收新的任务,但是执行队列中的任务
    private static final int STOP       =  1 << COUNT_BITS;    // 不接收新的任务,不再执行队列中的任务,中断正在执行的任务
    private static final int TIDYING    =  2 << COUNT_BITS;     //  所有任务已经中止,且工作线程数量为0,进入到这个状态将会执行terminated 钩子方法
    private static final int TERMINATED =  3 << COUNT_BITS;      //  中止状态,已经执行完terminated()钩子方法

线程池初始状态为 RUNNING;

  RUNNING - > SHUTDOWN  ,  执行 shutdown() 方法

  RUNNING - > STOP             ,   执行 shutdownNow() 方法

  SHUTDOWN - > STOP        ,  执行 shutdownNow() 方法

  STOP - > TIDYING               ,  执行 shutdown() 或者 shutdownNow() 后,所有任务已终止,且工作线程数量为0时,执行terminated() 方法。

  TIDYING -> TERMINATED  ,   执行完 terminated() 方法后。

 

shutdown方法:  做了两件事情:  1)修改了ctl的值,为SHUTDOWN状态     2) 将所有的线程的工作状态设置为了 true;

  public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);    // 设置成  SHUTDOWN 状态, 一定会设置成功
            interruptIdleWorkers();      // 设置所有的线程的中断状态为 ture.   目的是什么??
            onShutdown(); // hook for ScheduledThreadPoolExecutor     // 这个地方一看就不一般,在这里我们用不到
        } finally {
            mainLock.unlock();
        }
        tryTerminate();    // 
    }

ThreadPoolExecutor 中的 advanceRunState 方法:

  private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||      // 保证是 RUNNING 状态   因为 >= SHUTDOWN 条件满足,直接 break.
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))     // 设置成 SHUTDOWN状态,但是也只是改变了 ctl的值而已
                break;
        }
    }

ThreadPoolExecutor 中的 interruptIdleWorkers 方法。

   private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }

 

private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                if (!t.isInterrupted() && w.tryLock()) {  // 如果线程t的中断状态为 false, 上锁 (防止修改中断状态时被打扰???)
                    try {
                        t.interrupt();   // 将线程 t 的中断状态设置为  true
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)    // 用于设置一个线程的中断状态??  这里要设置所有的,为false, break语句不执行
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

 

 ThreadPoolExecutor 中的 tryTerminate 方法:

  final void tryTerminate() {
        for (;;) {     // 死循环
            int c = ctl.get();
            if (isRunning(c) ||      // 判断是否为 RUNNING 状态
                runStateAtLeast(c, TIDYING) ||    // 判断状态是否为 TIDYING 状态或者是 TERMINATED 状态
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))  // 状态是 SHUTDOWM状态 并且 阻塞队列为空
                return;      // 也就是 状态为 STOP状态 或者 SHUTDOWN状态 并且 阻塞队列为空  才会继续往下运行
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);      // ???  什么意思 ???
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {   // 设置 ctl的值  设置成 TIDYNING, 0个工作线程
                    try {
                        terminated();    // 是一个空函数  待解决
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));     // 设置 ctl 的值 , 设置成 TERMINATED, 0个工作线程。
                        termination.signalAll();   // 待解决
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

shutdownNow 方法:

   public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);  // 跟 shutdown 方法不一样的地方就是在这里
            interruptWorkers();
            tasks = drainQueue();  //  待解决 !!
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

 

 

  private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        q.drainTo(taskList);
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

 

 

 

ctl: 

变量 ctl 是 AtomicIntege类型, 它的高三位用来表示线程池的运行状态; 低29位用来表示线程池中的线程数量。

    ctl 在线程池中的源码中经常会看到,用于记录线程池的生命周期状态(runState)和 工作线程的数量( workerCountOf ) 。  为什么不用两个变量?

  

 

    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }     // 得到线程池的生命周期状态
    private static int workerCountOf(int c)  { return c & CAPACITY; }      // 得到线程池的工作线程数
    private static int ctlOf(int rs, int wc) { return rs | wc; }           // 通过线程池的生命周期状态 和 工作线程数,得到 ctl 的值

 

ThreadPoolExecutor中的 execute方法

  传入的形参要求是 Runnable 类型;

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();    // 得到的是 ctl的值, ctl是一个 AtomicInteger 类型的变量
        if (workerCountOf(c) < corePoolSize) {   // 如果 线程池中的工作线程数 小于 核心线程数
            if (addWorker(command, true))        //
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {  // 如果线程池是RUNNING状态,并且任务加入到阻塞队列成功
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))  // 如果不是RUNNING 生命周期 并且 阻塞队列中有任务
                reject(command);    // 执行拒绝策略
            else if (workerCountOf(recheck) == 0)  // 如果工作线程的数量为0 
                addWorker(null, false);
        }
        else if (!addWorker(command, false))   // 如果创建非核心线程失败 
            reject(command);  // 执行拒绝策略
    }

   

   1)ThreadPoolExecutor 中的 addWorker 方法

private boolean addWorker(Runnable firstTask, boolean core) {
        retry:     // retry 只是一个表示,可以自己随便起一个名字,  用在多重循环中跳出循环。 结合 continue 和 break 关键字来使用
        for (;;) {
            int c = ctl.get();  
            int rs = runStateOf(c);   // 得到线程池的运行状态(生命周期)

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&     // 线程池的生命周期为RUNNING 条件不满足,继续向后执行
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);  // 工作线程数量
                if (wc >= CAPACITY ||     // 如果工作线程数量 大于等于 2^29 - 1, 
                    wc >= (core ? corePoolSize : maximumPoolSize))   // 工作线程数量大于等于核心线程数 
                    return false;
                if (compareAndIncrementWorkerCount(c))     // 增加一个工作线程,没有实际增加,只是改变 ctl的值
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)     // 看一下在这期间线程池的生命周期状态是否发生了变化
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        boolean workerStarted = false;
        boolean workerAdded = false;
        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());   //得到线程池的生命周期状态

                    if (rs < SHUTDOWN ||  // 如果 是 RUNNING 状态
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable     // 判断线程是否已经开启???
                            throw new IllegalThreadStateException();
                        workers.add(w);    // 将新建的 woker 加入到 hashSet中
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();    // 这里才是开启的线程    这就是开始执行  run方法!!!!
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

 Worker 中的run方法:

     public void run() {
            runWorker(this);
        }

ThreadPoolExecutor 中的 runWorker 方法:

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;   // 要执行的任务
        w.firstTask = null;
        w.unlock(); // allow interrupts    // 占有锁了吗?? 释放的是谁的锁??? 待解决!!!!
        boolean completedAbruptly = true;
        try { 
            while (task != null || (task = getTask()) != null) {    // 因为在这个 while 循环中,所以 核心线程一致存活,没有被销毁。
                                         // getTask 用于从阻塞队列中获取任务 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 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); // 当没有任务要执行的时候 } }

ThreadPoolExecutor 中的 getTask 方法。

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {   // 只有当线程池的生命周期为RUNNING 或者 线程池的生命周期为SHUTDOWN 但是阻塞队列为NULL的时候,才会跳过去 
                decrementWorkerCount();   // 将ctl的值减一,
                return null;
            }

            int wc = workerCountOf(c);   // 获取线程池中的工作线程数量

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;   
                  // allowCoreThreadTimeOut 默认是false ,即核心线程默认空闲时仍然存活
                  // 所以当工作线程的数量 大于 核心线程数的时候 , timed 的值才为 true.
if ((wc > maximumPoolSize || (timed && timedOut)) // 如果工作线程数 大于了最大线程数 && (wc > 1 || workQueue.isEmpty())) { if (compareAndDecrementWorkerCount(c)) // 将ctl的值减1 return null; continue; } try { Runnable r = timed ? // 当前的工作线程数 是否 大于了 核心线程数 workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); // 获得阻塞队列中的任务 if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }

ThreadPoolExecutor 中的 processWorkerExit 方法:

 private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);    // 从工作线程集合中移除 当前工作线程
        } finally {
            mainLock.unlock();
        }

        tryTerminate();  // 作用是什么???

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);   // 又创建了一个线程???  非核心线程。
        }
    }

 

 

 

 

 

 

 

参考文档:

  https://blog.csdn.net/programmer_at/article/details/79799267?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3.not_use_machine_learn_pai

  ctl 变量解释的很好:

  https://www.cnblogs.com/moonfair/p/13477974.html

posted @ 2020-11-23 21:44  你眼里的星辰  阅读(109)  评论(0)    收藏  举报