JDK线程池源码浅析

2019-03-07  本文已影响0人  packet

出于功利的原因,很早之前就想搞清楚JDK线程池的原理,在工作不到一年的时候就点进源码去看了看,当然没看不懂。
后来搜索了多篇文章来读,看得模模糊糊。现在想起来,一点印象都没有。
今天看了一篇老文章,温故知新,给了我很大启发,借此谈谈怎样阅读源码。

  1. 源码并不神秘,虽然看起来复杂,但其规律是能被把握的。
  2. 源码不是看懂的,哪怕你用再多的时间。除了分析,还必须实践,否则徒劳无功。
  3. 想要用一大块完整的时间来看懂源码,是不现实的。因为对复杂事务的认知是分层次的,需要分清主次深浅。循序渐进,反复迭代,每次弄懂一小块,做好记录,迭代久了才可能有深入认知。切忌急躁贪功。
  4. 源码不必全部看懂,全看了也未必有益,但大体上能看出粗象,不然无法表达。
  5. 任何软件的初衷都是简单的,但随着迭代衍化,逻辑逐步变得庞大复杂。要学会忽略枝叶,看到主干,否则将陷入无穷的细节中。

现在回到线程池,可以归结为几个重要问题:

  1. ThreadPoolExecutor有哪些参数?有什么意义?
    corePoolSize: 核心线程数量,可以类比正式员工数量,常驻线程数量。
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

高3位表示线程池状态(一共5种),低29位表示线程数量。

  1. ThreadPoolExecutor 中的线程和普通线程有哪些不同之处?
private final class Worker  extends AbstractQueuedSynchronizer implements Runnable
  1. ThreadPoolExecutor 中的线程放在什么容器内?
    /**
     * Set containing all worker threads in pool. Accessed only when
     * holding mainLock.
     */
    private final HashSet<Worker> workers = new HashSet<Worker>();
    private final ReentrantLock mainLock = new ReentrantLock();
  1. ThreadPoolExecutor 中的多余的空闲线程怎样消失?
        try {
            while (task != null || (task = getTask()) != null) {
                // do sth

            }
        } finally {
            processWorkerExit(w, completedAbruptly); // 从works中删除
        }

getTask()是关键方法,核心代码:

int wc = workerCountOf(c);
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
Runnable r = timed ?   workQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS) :
                    workQueue.take();
if (r != null)
        return r;

这里只是粗略介绍一下,但是有了这点知识,就大概能有一个轮廓。
至于深入细节……

鸣谢:深入源码分析Java线程池的实现原理

上一篇 下一篇

猜你喜欢

热点阅读