Android && Java 線程池的工作原理

1、構造方法

public ThreadPoolExecutor(int corePoolSize,                     //核心線程數
                          int maximumPoolSize,                  //線程池最大容量
                          long keepAliveTime,                   //線程保活時間,實現方式是:延時從任務隊列取任務。
                          TimeUnit unit,                        //保活時間單位
                          BlockingQueue<Runnable> workQueue,    //任務隊列
                          ThreadFactory threadFactory)          //創建線程工廠

BlockingQueue<Runnable> workQueue;          //任務隊列。如果當前沒有空閑線程,任務會存儲到此隊列。隊列由用戶創建,通過構造方法傳進來。
HashSet<Worker> workers = new HashSet<>();  //工作的線程Set,工作線程和空閑線程都存儲在這里。

2、 public void execute(Runnable command)方法發送任務給線程池。

  • 如果當前線程數沒有達到最大核心線程數,會創建核心線程。
  • 否則會把任務添加進任務隊列,然后再創建非核心線程。
  • (創建線程方法addWorker(Runnable firstTask, boolean core),core是線程種類,核心/非核心。是否達到最大線程數,是在創建過程中判斷的。)

3、 addWorker(Runnable firstTask, boolean core)

一、 addWorker創建一個工作線程是通過創建一個包含一個Thread的Worker類。
二、 Worker本身繼承了Runnable接口,包含run()方法。把自己傳入自己包含的Thread變量中執行。
三、 addWorker中有調用了worker.thread.start(), 就在新的線程中執行了其包含的Runnable(worker),調用了worker的run()方法,中的runWorker(),方法。

private final class Worker
    extends AbstractQueuedSynchronizer
    implements Runnable {
    ...
     Worker(Runnable firstTask) {
                setState(-1); // inhibit interrupts until runWorker
                this.firstTask = firstTask;
                this.thread = getThreadFactory().newThread(this);
    }
    public void run() {
        runWorker(this);
    }
    ...
}

4、 runWorker(Worker w)方法已經在新的線程中運行。

新線程中通過while循環執行task,Worker中的task不為空就執行,如果Worker中的task為空,就通過getTask()方法取任務隊列中的任務。

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    try {
        while (task != null || (task = getTask()) != null) {
        ...
        }

5、 Runnable getTask()獲取任務隊列中的任務。

線程保活時間也是從這里完成的。延時的從任務隊列中取任務,如果延時后取出為null,線程結束。如果取出了,就繼續在當前線程中執行Runnable任務。也完成了,線程池的復用和任務隊列的順序執行。

private Runnable getTask() {

    for (;;) {

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

        try {
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容