国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

java線程池的原理學(xué)習(xí)(三)

mgckid / 1698人閱讀

摘要:接上文線程池的原理學(xué)習(xí)二深入剖析線程池的五種狀態(tài)類(lèi)中將線程狀態(tài)分為了以下五種可以接受新任務(wù)并且處理進(jìn)入隊(duì)列中的任務(wù)不接受新任務(wù),但是仍然執(zhí)行隊(duì)列中的任務(wù)不接受新任務(wù)也不執(zhí)行隊(duì)列中的任務(wù)所有任務(wù)中止,隊(duì)列為空,進(jìn)入該狀態(tài)下的任務(wù)會(huì)執(zhí)行方法方法

接上文:java線程池的原理學(xué)習(xí)(二)

ThreadPoolExecutor深入剖析 線程池的五種狀態(tài)

ThreadPoolExecutor 類(lèi)中將線程狀態(tài)( runState)分為了以下五種:

RUNNING:可以接受新任務(wù)并且處理進(jìn)入隊(duì)列中的任務(wù)
SHUTDOWN:不接受新任務(wù),但是仍然執(zhí)行隊(duì)列中的任務(wù)
STOP:不接受新任務(wù)也不執(zhí)行隊(duì)列中的任務(wù)
TIDYING:所有任務(wù)中止,隊(duì)列為空,進(jìn)入該狀態(tài)下的任務(wù)會(huì)執(zhí)行 terminated()方法
TERMINATEDterminated()方法執(zhí)行完成后進(jìn)入該狀態(tài)

狀態(tài)之間的轉(zhuǎn)換

RUNNING -> SHUTDOWN

調(diào)用了 shutdown()方法,可能是在 finalize()方法中被隱式調(diào)用

(RUNNING or SHUTDOWN) -> STOP

調(diào)用 shutdownNow()

SHUTDOWN -> TIDYING

當(dāng)隊(duì)列和線程池都為空時(shí)

STOP -> TIDYING

線程池為空時(shí)

TIDYING -> TERMINATED

terminated()方法執(zhí)行完成

線程池狀態(tài)實(shí)現(xiàn)

如果查看 ThreadPoolExecutor的源碼,會(huì)發(fā)現(xiàn)開(kāi)頭定義了這幾個(gè)變量來(lái)代表線程狀態(tài)和活動(dòng)線程的數(shù)量:

    //原子變量
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // 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;
    private static final int TERMINATED =  3 << COUNT_BITS;

這個(gè)類(lèi)中將二進(jìn)制數(shù)分為了兩部分,高位代表線程池狀態(tài)( runState),低位代表活動(dòng)線程數(shù)( workerCount), CAPACITY代表最大的活動(dòng)線程數(shù),為2^29-1,下面為了更直觀的看到這些數(shù)我做了些打?。?/p>

public class Test1 {
    public static void main(String[] args) {
            final int COUNT_BITS = Integer.SIZE - 3;
            final int CAPACITY   = (1 << COUNT_BITS) - 1;

            final int RUNNING    = -1 << COUNT_BITS;
            final int SHUTDOWN   =  0 << COUNT_BITS;
            final int STOP       =  1 << COUNT_BITS;
            final int TIDYING    =  2 << COUNT_BITS;
            final int TERMINATED =  3 << COUNT_BITS;
            
            System.out.println(Integer.toBinaryString(CAPACITY));
            System.out.println(Integer.toBinaryString(RUNNING));
            System.out.println(Integer.toBinaryString(SHUTDOWN));
            System.out.println(Integer.toBinaryString(STOP));
            System.out.println(Integer.toBinaryString(TIDYING));
            System.out.println(Integer.toBinaryString(TERMINATED));
    }
}

輸出:

11111111111111111111111111111
11100000000000000000000000000000
0
100000000000000000000000000000
1000000000000000000000000000000
1100000000000000000000000000000

打印的時(shí)候會(huì)將高位0省略
可以看到,第一行代表線程容量,后面5行提取高3位得到:

111 - RUNNING
000 - SHUTDOWN
001 - STOP
010 - TIDYING
011 - TERMINATED

分別對(duì)應(yīng)5種狀態(tài),可以看到這樣定義之后,只需要通過(guò)簡(jiǎn)單的移位操作就可以進(jìn)行狀態(tài)的轉(zhuǎn)換。

重要方法

execute方法:

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
       
        int c = ctl.get();
        /**分三步執(zhí)行
         * 如果workerCount=corePoolSize,判斷線程池是否處于運(yùn)行狀態(tài),再將任務(wù)加入隊(duì)列
         * */
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();     //用于double check
            //如果線程池處于非運(yùn)行態(tài),則將任務(wù)從緩存隊(duì)列中刪除
            if (! isRunning(recheck) && remove(command)) 
                reject(command);  //拒絕任務(wù)
            else if (workerCountOf(recheck) == 0) //如果活動(dòng)線程數(shù)為0,則創(chuàng)建新線程
                addWorker(null, false);
        }
        //如果線程池不處于RUNNING狀態(tài),或者workQueue滿了,則執(zhí)行以下代碼
        else if (!addWorker(command, false))
            reject(command);
    }

可以看到,在類(lèi)中使用了 Work類(lèi)來(lái)代表任務(wù),下面是 Work類(lèi)的簡(jiǎn)單摘要:

private final class Worker extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread;
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;
        /** Per-thread task counter */
        volatile long completedTasks;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }
        ...

Work類(lèi)實(shí)現(xiàn)了 Runnable接口,使用了線程工廠創(chuàng)建線程,使用 runWork方法來(lái)運(yùn)行任務(wù)
創(chuàng)建新線程時(shí)用到了 addWorker()方法:

/**
     * 檢查在當(dāng)前線程池狀態(tài)和限制下能否創(chuàng)建一個(gè)新線程,如果可以,會(huì)相應(yīng)改變workerCount,
     * 每個(gè)worker都會(huì)運(yùn)行他們的firstTask
     * @param firstTask 第一個(gè)任務(wù)
     * @param core true使用corePoolSize作為邊界,false使用maximumPoolSize
     * @return false 線程池關(guān)閉或者已經(jīng)具備關(guān)閉的條件或者線程工廠沒(méi)有創(chuàng)建新線程
     */
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // 只有當(dāng)rs < SHUTDOWN才有可能接受新任務(wù)
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c); //工作線程數(shù)量
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize)) //不合法則返回
                    return false;
                if (compareAndIncrementWorkerCount(c)) //將工作線程數(shù)量+1
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs) //判斷線程池狀態(tài)有沒(méi)有改變,改變了則進(jìn)行外循環(huán),否則只進(jìn)行內(nèi)循環(huán)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }
        //創(chuàng)建新線程
        Worker w = new Worker(firstTask);
        Thread t = w.thread;

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //再次檢查狀態(tài),防止ThreadFactory創(chuàng)建線程失敗或者狀態(tài)改變了
            int c = ctl.get();
            int rs = runStateOf(c);

            if (t == null ||
                (rs >= SHUTDOWN &&
                 ! (rs == SHUTDOWN &&
                    firstTask == null))) {
                decrementWorkerCount();  //減少線程數(shù)量
                tryTerminate();//嘗試中止線程
                return false;
            }

            workers.add(w);//添加到工作線程Set集合中

            int s = workers.size();
            if (s > largestPoolSize)
                largestPoolSize = s;
        } finally {
            mainLock.unlock();
        }

        t.start();//執(zhí)行任務(wù)
       //狀態(tài)變成了STOP(調(diào)用了shutdownNow方法)
        if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
            t.interrupt();

        return true;
    }

再看 Work中runWork方法:

final void runWorker(Worker w) {
        Runnable task = w.firstTask;
        w.firstTask = null;
        boolean completedAbruptly = true;//線程是否異常中止
        try {
            //先取firstTask,再?gòu)年?duì)列中取任務(wù)直到為null
            while (task != null || (task = getTask()) != null) {
                w.lock();
                clearInterruptsForTaskRun();
                try {
                    beforeExecute(w.thread, task);//實(shí)現(xiàn)鉤子方法
                    Throwable thrown = null;
                    try {
                        task.run();//運(yùn)行任務(wù)
                    } 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);//實(shí)現(xiàn)鉤子方法
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;//成功運(yùn)行,說(shuō)明沒(méi)有異常中止
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/64431.html

相關(guān)文章

  • 后端ing

    摘要:當(dāng)活動(dòng)線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來(lái)進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請(qǐng)求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...

    roadtogeek 評(píng)論0 收藏0
  • 技術(shù)經(jīng)理:求求你,別再亂改數(shù)據(jù)庫(kù)連接池的大小了!

    摘要:你僅僅需要一個(gè)大小為數(shù)據(jù)庫(kù)連接池,然后讓剩下的業(yè)務(wù)線程都在隊(duì)列里等待就可以了。你應(yīng)該經(jīng)常會(huì)看到一些用戶(hù)量不是很大的應(yīng)用中,為應(yīng)付大約十來(lái)個(gè)的并發(fā),卻將數(shù)據(jù)庫(kù)連接池設(shè)置成,的情況。請(qǐng)不要過(guò)度配置您的數(shù)據(jù)庫(kù)連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關(guān)注個(gè)人微信公眾...

    darkbug 評(píng)論0 收藏0
  • 技術(shù)經(jīng)理:求求你,別再亂改數(shù)據(jù)庫(kù)連接池的大小了!

    摘要:你僅僅需要一個(gè)大小為數(shù)據(jù)庫(kù)連接池,然后讓剩下的業(yè)務(wù)線程都在隊(duì)列里等待就可以了。你應(yīng)該經(jīng)常會(huì)看到一些用戶(hù)量不是很大的應(yīng)用中,為應(yīng)付大約十來(lái)個(gè)的并發(fā),卻將數(shù)據(jù)庫(kù)連接池設(shè)置成,的情況。請(qǐng)不要過(guò)度配置您的數(shù)據(jù)庫(kù)連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關(guān)注個(gè)人微信公眾...

    蘇丹 評(píng)論0 收藏0
  • java線程池的原理學(xué)習(xí)(二)

    摘要:接上文線程池的原理學(xué)習(xí)簡(jiǎn)單介紹,線程池類(lèi),繼承自構(gòu)造方法提供了四種構(gòu)造方法實(shí)現(xiàn)這里只介紹一種有必要對(duì)每個(gè)參數(shù)解釋一下池中所保存的線程數(shù),包括空閑線程。文檔中提供了一個(gè)可以暫停和恢復(fù)的線程池例子運(yùn)行原理線程池的原理學(xué)習(xí)三 接上文:java線程池的原理學(xué)習(xí) ThreadPoolExecutor簡(jiǎn)單介紹 ThreadPoolExecutor,線程池類(lèi),繼承自 AbstractExecutor...

    oujie 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<