Java線程池的原理

先上個網(wǎng)圖說明下線程池的執(zhí)行過程


image.png

來看下線程池的執(zhí)行過程


image.png

1.當(dāng)線程池數(shù)量小于核心線程數(shù) 直接創(chuàng)建核心線程
2.隊列是否已滿,沒有的話 放入隊列

3.放入隊列失敗 添加非核心線程 失敗的話 處理失敗

很容易看出核心方法是addWork 這個方法是添加線程執(zhí)行的,不做過多解釋。
在這個方法中調(diào)用了 start 方法,這個很熟悉是啟動線程的方法。
順藤破瓜看看Work的run方法 只有一個runWork方法

 final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
           // 保證核心線程默認(rèn)情況下不會被銷毀而是進(jìn)行阻塞(getTask()核心線程)
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // 死循環(huán)保證線程不會結(jié)束 
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        //執(zhí)行真正的任務(wù)
                        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的執(zhí)行 包含了線程阻塞

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())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                // 線程結(jié)束
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    // 非核心線程超過時間會被淘汰 返回null 退出線程
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                   // 小于核心線程,當(dāng)前待線程為0  阻塞線程保證默認(rèn)情況下的核心線程不會銷毀
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

大體意思就是
不停的取task
超時退出線程
沒有任務(wù)時 阻塞線程 可以設(shè)置核心線程可以退出,這個時候線程不會阻塞

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容