天天看點

ThreadPoolExecutor線程池參考資料

繼續來學習Doug Lea大神的代碼

線程池

線程池的狀态:

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,

he thread transitioning to state TIDYING

will run the terminated() hook method

TERMINATED: terminated() has completed

RUNNING -> SHUTDOWN:shutdown()

SHUTDOWN -> TIDYING:隊列和線程池均為空

STOP -> TIDYING:線程池為空

TIDYING -> TERMINATED:terminated()

最核心的構造函數:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
           

corePoolSize:線程池中最大的核心線程的數量,核心線程即為即使處于等待狀态也不會被銷毀的線程

maximumPoolSize:線程池允許的最大線程數

keepAliveTime:當線程池中線程數量大于核心線程數量時,工作線程的最大等待時間,過了等待時間工作線程會被終止

unit:時間的機關

workQueue:任務被處理之前等待的隊列

threadFactory:線程工廠

handler:當線程池和阻塞隊列全部滿的時候對新任務的處理方式

execute

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }
           

1、如果線程池内線程數小于corePoolSize,則每來一個任務就建立一個核心線程去處理;

2、如果線程池内線程數小于corePoolSize,小于maximumPoolSize,往阻塞隊列插入任務;

3、如果2中插入失敗,那麼直接添加一個工作線程來處理;

4、如果2中插入成功,等待空閑線程來取任務執行,如果線程池線程數為0,添加一個線程來處理任務;如果線程池不處于運作狀态并且任務删除成功,拒絕後面的任務。

ThreadPoolExecutor線程池參考資料

參考資料

jdk 1.8中的線程池 作者: EnjoyCodingEnjoyLife

java6的實作 作者: Matrix海子