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

資訊專欄INFORMATION COLUMN

ThreadPoolExecutor淺談

garfileo / 744人閱讀

摘要:耐心看完的你或多或少會有收獲的解釋在了解線程池之前,希望你已經(jīng)了解了內(nèi)存模型和前位表示運(yùn)行狀態(tài),后面位存儲當(dāng)前運(yùn)行最大容量實(shí)際線程池大小還是由決定以下為線程池的幾個(gè)狀態(tài)官方注釋在最上方接受新的任務(wù)不接受新的任務(wù),但是已在

耐心看完的你或多或少會有收獲!

ThreadPoolExecutor field 的解釋

在了解線程池之前,希望你已經(jīng)了解了 Java內(nèi)存模型 和 AQS CAS

     /**                    
     * The runState provides the main lifecycle control, taking on values:
     *
     *   RUNNING:  Accept new tasks and process queued tasks
     *   SHUTDOWN: Don"t accept new tasks, but process queued tasks
     *   STOP:     Don"t accept new tasks, don"t process queued tasks,
     *             and interrupt in-progress tasks
     *   TIDYING:  All tasks have terminated, workerCount is zero,
     *             the thread transitioning to state TIDYING
     *             will run the terminated() hook method
     *   TERMINATED: terminated() has completed
     *
     * The numerical order among these values matters, to allow
     * ordered comparisons. The runState monotonically increases over
     * time, but need not hit each state. The transitions are:
     *
     * RUNNING -> SHUTDOWN
     *    On invocation of shutdown(), perhaps implicitly in finalize()
     * (RUNNING or SHUTDOWN) -> STOP
     *    On invocation of shutdownNow()
     * SHUTDOWN -> TIDYING
     *    When both queue and pool are empty
     * STOP -> TIDYING
     *    When pool is empty
     * TIDYING -> TERMINATED
     *    When the terminated() hook method has completed terminated()
     */
    
    // 前 3 位表示運(yùn)行狀態(tài),后面 29 位存儲當(dāng)前運(yùn)行 workerCount
    private static final int COUNT_BITS = Integer.SIZE - 3; // 32 - 3
    
    // 最大容量
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1; // 00011111111111111111111111111111
   
    /**
     * Maximum pool size. Note that the actual maximum is internally
     * bounded by CAPACITY. 實(shí)際線程池大小還是由 CAPACITY 決定
     */
    private volatile int maximumPoolSize;
    
    // 以下為線程池的幾個(gè)狀態(tài) 官方注釋在最上方
    // 接受新的任務(wù)
    private static final int RUNNING    = -1 << COUNT_BITS; // 11100000000000000000000000000000
    
    // 不接受新的任務(wù),但是已在隊(duì)列中的任務(wù),還會繼續(xù)處理
    private static final int SHUTDOWN   =  0 << COUNT_BITS; // 00000000000000000000000000000000
    
    // 不接受,不處理新的任務(wù),且中斷正在進(jìn)行中的任務(wù)
    private static final int STOP       =  1 << COUNT_BITS; // 00100000000000000000000000000000
    
    // 所有任務(wù)已停止,workerCount 清零,注意 workerCount 是由 workerCountOf(int c) 計(jì)算得出的
    private static final int TIDYING    =  2 << COUNT_BITS; // 01000000000000000000000000000000
    
    // 所有任務(wù)已完成
    private static final int TERMINATED =  3 << COUNT_BITS; // 01100000000000000000000000000000
    
    // 線程池運(yùn)行狀態(tài)和已工作的 workerCount 初始化為 RUNNING 和 0
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    
    // 計(jì)算當(dāng)前 state
    // ~CAPACITY 為 11100000000000000000000000000000 & c(假如前三位為 000 說明線程池已經(jīng) SHUTDOWN)
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    
    // 同時(shí)拿到 state workerCount
    private static int ctlOf(int rs, int wc) { return rs | wc; }
    
    // 可以計(jì)算出當(dāng)前工作的 workerCount
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    
    // 線程入列
    public void execute(Runnable command) {
            if (command == null)
                throw new NullPointerException();
       
            // 獲得當(dāng)前 state 和 workerCount
            // 判斷是否滿足加入核心線程
            int c = ctl.get();
            if (workerCountOf(c) < corePoolSize) {
                // 以核心線程的方式加入隊(duì)列
                if (addWorker(command, true))
                    return;
                // 添加失敗 獲取最新的線程池 state 和 workerCount
                c = ctl.get();
            }
            // 在運(yùn)行且成功加入隊(duì)列
            if (isRunning(c) && workQueue.offer(command)) {
                int recheck = ctl.get();
                // 再檢查一次,不在運(yùn)行就拒絕任務(wù)
                if (!isRunning(recheck) && remove(command))
                    reject(command);
                else if (workerCountOf(recheck) == 0)
                    // 加入一個(gè) null
                    addWorker(null, false);
            }
            // 加入失敗就拒絕任務(wù)
            else if (!addWorker(command, false))
                reject(command);
        }
    
    // 實(shí)際的操作
    private boolean addWorker(Runnable firstTask, boolean core) {
            retry:
            for (;;) {
                // 獲得當(dāng)前 state 和 workerCount
                int c = ctl.get();
                int rs = runStateOf(c);
    
                // 大于 SHUTDOWN 即 STOP TIDYING TERMINATED
                // Check if queue empty only if necessary.
                if (rs >= SHUTDOWN &&
                    ! (rs == SHUTDOWN &&
                       firstTask == null &&
                       ! workQueue.isEmpty()))
                    return false;
    
                for (;;) {
                    // 計(jì)算 workerCount
                    int wc = workerCountOf(c);
                    if (wc >= CAPACITY ||
                        wc >= (core ? corePoolSize : maximumPoolSize))
                        return false;
                    // 成功了就退出
                    if (compareAndIncrementWorkerCount(c))
                        break retry;
                    c = ctl.get();  // Re-read ctl
                    if (runStateOf(c) != rs)
                        // 走到這一步說明 rs 為 RUNNING 或 SHUTDOWN 可以重新嘗試加入
                        continue retry;
                    // else CAS failed due to workerCount change; retry inner loop
                }
            }
    
            boolean workerStarted = false;
            boolean workerAdded = false;
            Worker w = null;
            try {
                // 統(tǒng)一線程的名字
                // 設(shè)置 daemon 和 priority
                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 ||
                            (rs == SHUTDOWN && firstTask == null)) {
                            if (t.isAlive()) // precheck that t is startable
                                throw new IllegalThreadStateException();
                            workers.add(w);
                            int s = workers.size();
                            if (s > largestPoolSize)
                                largestPoolSize = s;
                            workerAdded = true;
                        }
                    } finally {
                        mainLock.unlock();
                    }
                    // 添加成功 啟動線程
                    if (workerAdded) {
                        t.start();
                        workerStarted = true;
                    }
                }
            } finally {
                // 加入失敗 
                if (! workerStarted)
                    addWorkerFailed(w);
            }
            return workerStarted;
        }
        
    // 加入失敗 做一些掃尾清理
    private void addWorkerFailed(Worker w) {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (w != null)
                    workers.remove(w);
                // workerCount-1
                decrementWorkerCount();
                // 嘗試更新狀態(tài) 何為嘗試,即需要滿足一定條件,而不是冒然去做某事
                tryTerminate();
            } finally {
                mainLock.unlock();
            }
        }
總結(jié)一下

寫得好的源碼,注釋一定要好好看一遍

線程池的狀態(tài)和工作線程數(shù)量用 32 位二進(jìn)制數(shù)表示,然后通過二進(jìn)制的位運(yùn)算獲取狀態(tài)和數(shù)量,這種設(shè)計(jì)實(shí)在是太過精妙

膜拜大師

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

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

相關(guān)文章

  • 淺談Java并發(fā)編程系列(六) —— 線程池的使用

    摘要:線程池的作用降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的資源浪費(fèi)。而高位的部分,位表示線程池的狀態(tài)。當(dāng)線程池中的線程數(shù)達(dá)到后,就會把到達(dá)的任務(wù)放到中去線程池的最大長度。默認(rèn)情況下,只有當(dāng)線程池中的線程數(shù)大于時(shí),才起作用。 線程池的作用 降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的資源浪費(fèi)。 提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),不需要等到線程創(chuàng)建就能立即執(zhí)行...

    Vicky 評論0 收藏0
  • ThreadPoolExecutor策略配置以及應(yīng)用場景

    摘要:支持通過調(diào)整構(gòu)造參數(shù)來配置不同的處理策略,本文主要介紹常用的策略配置方法以及應(yīng)用場景。對于這種場景,我們可以設(shè)置使用帶有長度限制的隊(duì)列以及限定最大線程個(gè)數(shù)的線程池,同時(shí)通過設(shè)置處理任務(wù)被拒絕的情況。 ThreadPoolExecutor 是用來處理異步任務(wù)的一個(gè)接口,可以將其理解成為一個(gè)線程池和一個(gè)任務(wù)隊(duì)列,提交到 ExecutorService 對象的任務(wù)會被放入任務(wù)隊(duì)或者直接被線程...

    tuantuan 評論0 收藏0
  • (十七)java多線程之ThreadPoolExecutor

    摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載引言在之前的例子我們要?jiǎng)?chuàng)建多個(gè)線程處理一批任務(wù)的時(shí)候我是通過創(chuàng)建線程數(shù)組或者使用線程集合來管理的但是這樣做不太好因?yàn)檫@些線程沒有被重復(fù)利用所以這里要引入線程池今天我們就講線程 本人郵箱: 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明網(wǎng)址 http://blog.csdn.net/tianshi_kcogithub: https://github...

    wpw 評論0 收藏0
  • 使用 Executors,ThreadPoolExecutor,創(chuàng)建線程池,源碼分析理解

    摘要:源碼分析創(chuàng)建可緩沖的線程池。源碼分析使用創(chuàng)建線程池源碼分析的構(gòu)造函數(shù)構(gòu)造函數(shù)參數(shù)核心線程數(shù)大小,當(dāng)線程數(shù),會創(chuàng)建線程執(zhí)行最大線程數(shù),當(dāng)線程數(shù)的時(shí)候,會把放入中保持存活時(shí)間,當(dāng)線程數(shù)大于的空閑線程能保持的最大時(shí)間。 之前創(chuàng)建線程的時(shí)候都是用的 newCachedThreadPoo,newFixedThreadPool,newScheduledThreadPool,newSingleThr...

    Chiclaim 評論0 收藏0
  • 一看就懂的Java線程池分析詳解

    摘要:任務(wù)性質(zhì)不同的任務(wù)可以用不同規(guī)模的線程池分開處理。線程池在運(yùn)行過程中已完成的任務(wù)數(shù)量。如等于線程池的最大大小,則表示線程池曾經(jīng)滿了。線程池的線程數(shù)量。獲取活動的線程數(shù)。通過擴(kuò)展線程池進(jìn)行監(jiān)控。框架包括線程池,,,,,,等。 Java線程池 [toc] 什么是線程池 線程池就是有N個(gè)子線程共同在運(yùn)行的線程組合。 舉個(gè)容易理解的例子:有個(gè)線程組合(即線程池,咱可以比喻為一個(gè)公司),里面有3...

    Yangder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<