線程池

1.原因

創(chuàng)建線程與銷毀線程需要消耗資源,

2.目的

保活線程,提高系統(tǒng)的性能

3.線程池包含任務(wù)隊(duì)列與線程池子

1)任務(wù)隊(duì)列獲取任務(wù)
2)沒(méi)有任務(wù)時(shí)阻塞
3)queueSize和core線程數(shù)(執(zhí)行任務(wù)的線程數(shù),也就是初始化線程數(shù))、max線程數(shù),當(dāng)超core線程數(shù)并且queueSize達(dá)到了最大值,且線程數(shù)沒(méi)有超過(guò)max,那么啟動(dòng)新的線程
4)keepalive時(shí)間,超出core線程數(shù)的數(shù)量,設(shè)置存活時(shí)間,超出這個(gè)時(shí)間之后,回收線程,節(jié)約資源。這么設(shè)計(jì)原因?為了防止流量突然上漲
5) 任務(wù)隊(duì)列是多線程競(jìng)爭(zhēng)的是不是需要同步?
java中同步隊(duì)列是BlockingQueue接口
6)當(dāng)隊(duì)列滿了且達(dá)到了MAX線程數(shù)的大小如何處理?
RejectHandler接口,默認(rèn)拋出RejectException

4.Future接口

1)需要查看任務(wù)是否執(zhí)行完畢或者拋出異常
2)需要等待任務(wù)執(zhí)行完成
runnable 沒(méi)有返回值,不能拋出異常,callable則可以

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    // c = -536870911(狀態(tài)位)
    int c = ctl.get();
    //  工作線程數(shù)量小于核心線程池設(shè)定數(shù),則創(chuàng)建線程。
    if (workerCountOf(c) < corePoolSize) {
        // 如果添加成功則直接返回
        if (addWorker(command, true))
            return;
        // 否則再次獲取活動(dòng)線程數(shù)量
        c = ctl.get();
    }
    // 如果線程池正在運(yùn)行,并且添加進(jìn)隊(duì)列成功
    if (isRunning(c) && workQueue.offer(command)) {
        // 再次對(duì)線程池狀態(tài)檢查, 因?yàn)樯厦?addWorker 過(guò)了并且失敗了,所以需要檢查
        int recheck = ctl.get();
        // 如果狀態(tài)不是運(yùn)行狀態(tài),且從隊(duì)列刪除該任務(wù)成功并嘗試停止線程池
        if (! isRunning(recheck) && remove(command))
            // 拒絕任務(wù)
            reject(command);
        // 如果當(dāng)前工作線程數(shù)量為0(線程池已關(guān)閉),則添加一個(gè) null 到隊(duì)列中
        else if (workerCountOf(recheck) == 0)
            // 添加個(gè)空的任務(wù)
            addWorker(null, false);
    }
    // 如果添加隊(duì)列失敗,則創(chuàng)建一個(gè)任務(wù)線程,如果失敗,則拒絕
    else if (!addWorker(command, false))
        // 拒絕
        reject(command);
    }
}

addwork 創(chuàng)建線程 , workQueue.offer(command) 添加隊(duì)列(將任務(wù)添加到阻塞隊(duì)列中)
如果正在工作的的線程小于設(shè)置的核心線程,則創(chuàng)建線程,如過(guò)正在工作的線程大于核心線程數(shù),則試圖放入任務(wù)的隊(duì)列,如果失敗,則嘗創(chuàng)建一個(gè)maxnumpoolSize的任務(wù),注意:在remove方法中,該方法已經(jīng)試圖停止線程池的運(yùn)行

1) addWorker方法 - 創(chuàng)建線程池
private boolean addWorker(Runnable firstTask, boolean core)

第一個(gè)參數(shù)為Runnable 類型,代表線程池中的某個(gè)線程的第一個(gè)任務(wù),第二個(gè)參數(shù)如果是true,則創(chuàng)建核心線程,如果是false,則創(chuàng)建maxnumPoolSize 線程,這兩個(gè)線程的生命周期是不同的。

2) Worker.runWorker(Worker w) 方法——-線程池的最核心方法
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) {
                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);
        }
    }

首先執(zhí)行firstTask的run方法,然后循環(huán)獲取阻塞隊(duì)列中的任務(wù),并且調(diào)用他們的run方法,如果線程池中的任務(wù)異常,則拋出異常并停止運(yùn)行線程池。
初始化的核心線程數(shù)是直接調(diào)用start方法啟動(dòng)線程的,啟動(dòng)之后,這個(gè)線程不關(guān)閉,而是在阻塞隊(duì)列上等待,如果有任務(wù)就會(huì)執(zhí)行任務(wù)的run方法,而不是start方法

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

相關(guān)閱讀更多精彩內(nèi)容

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