精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Java線程進階之ThreadPoolExecutor線程池執行原理機制詳解

開發 前端
線程池中,把線程的狀態和數量通過int類型進行維護,高三位表示狀態,低29位表示線程數量。這樣可以保證線程的狀態和數量的一致性。

[[423243]]

前言

線程池有很多優點:

降低資源消耗;

提高響應速度;

提高線程的可管理性等等;

今天我們就來分析探討下原理實現

一、線程池接口簡單分析

1、Executor接口

  1. public interface Executor { 
  2. // 執行一個任務。任務都被封裝成Runnable的實現 
  3.     void execute(Runnable command); 

2、 ExecutorService接口

  1. public interface ExecutorService extends Executor { 
  2. // 啟動有序的關閉,之前提交的任務將會被執行,但不會接受新的任務。 
  3.     void shutdown(); 
  4. // 嘗試停止所有正在執行的任務,停止等待處理的任務,病返回任務列表 
  5.     List<Runnable> shutdownNow(); 
  6. // 判斷線程池是否已經關閉 
  7.     boolean isShutdown(); 
  8. // 如果關閉后所有任務都已完成。但是前提是必須先執行:shutdown 或者 shutdownNow 
  9.     boolean isTerminated(); 
  10. // 在開啟shutdown之后,阻止所有的任務知道執行完成 
  11.     boolean awaitTermination(long timeout, TimeUnit unit) 
  12.         throws InterruptedException; 
  13. // 提交任務,帶返回結果的 
  14.     <T> Future<T> submit(Callable<T> task); 
  15. // 提交任務,封裝返回結果為T 
  16.     <T> Future<T> submit(Runnable task, T result); 
  17.  // 提交一個普通任務,返回結果任意 
  18.     Future<?> submit(Runnable task); 
  19. // 執行一批任務,返回結果為 List<Future<T>> 
  20.     <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) 
  21.         throws InterruptedException; 
  22.     <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, 
  23.                                   long timeout, TimeUnit unit) 
  24.         throws InterruptedException; 
  25.     <T> T invokeAny(Collection<? extends Callable<T>> tasks) 
  26.         throws InterruptedException, ExecutionException; 
  27.     <T> T invokeAny(Collection<? extends Callable<T>> tasks, 
  28.                     long timeout, TimeUnit unit) 
  29.         throws InterruptedException, ExecutionException, TimeoutException; 

其具有5個核心的內部類。其中4內部類對應的是拒絕策略。Worker是核心的執行代碼;

3、 RejectedExecutionHandler

  1. public interface RejectedExecutionHandler { 
  2. // 拒絕執行策略 
  3.     void rejectedExecution(Runnable r, ThreadPoolExecutor executor); 

4、 AbortPolicy 策略

Java線程池默認的阻塞策略,不執行此任務,而且直接拋出一個運行時異常

  1. public static class AbortPolicy implements RejectedExecutionHandler { 
  2.         public AbortPolicy() { } 
  3.         // 直接拋出異常,描述前線程的基本信息 
  4.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 
  5.             throw new RejectedExecutionException("Task " + r.toString() + 
  6.                                                  " rejected from " + 
  7.                                                  e.toString()); 
  8.         } 
  9.     } 

5、DiscardPolicy策略

空方法,不做任何處理

  1. public static class DiscardPolicy implements RejectedExecutionHandler { 
  2.         public DiscardPolicy() { } 
  3.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 
  4.         } 
  5.     } 

6、DiscardOldestPolicy 策略

從隊列里面拋棄一個最老的任務,并再次execute 此task

  1. public static class DiscardOldestPolicy implements RejectedExecutionHandler { 
  2.         public DiscardOldestPolicy() { } 
  3.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 
  4.             if (!e.isShutdown()) { 
  5.             // 從隊列里面取出最老的一個任務 
  6.                 e.getQueue().poll(); 
  7.                 // 手動調用execute方法執行,將任務添加到隊列中 
  8.                 e.execute(r); 
  9.             } 
  10.         } 
  11.     } 

7、CallerRunsPolicy 策略

  1. public static class CallerRunsPolicy implements RejectedExecutionHandler { 
  2.         /** 
  3.          * Creates a {@code CallerRunsPolicy}. 
  4.          */ 
  5.         public CallerRunsPolicy() { } 
  6.       // 如果當前線程池沒有關閉,則調用線程的run方法 
  7.         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 
  8.             if (!e.isShutdown()) { 
  9.                 r.run(); 
  10.             } 
  11.         } 
  12.     } 

8、ThreadPoolExecutor

構造函數詳解

  1. public class ThreadPoolExecutor extends AbstractExecutorService { 
  2. public ThreadPoolExecutor(int corePoolSize, 
  3.                               int maximumPoolSize, 
  4.                               long keepAliveTime, 
  5.                               TimeUnit unit, 
  6.                               BlockingQueue<Runnable> workQueue) { 
  7.         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, 
  8.              Executors.defaultThreadFactory(), defaultHandler); 
  9.     } 

構造函數參數說明:

  • corePoolSize:線程池中的核心線程數,空閑時候線程也不會回收,除非把allowCoreThreadTimeOut設置為 true,這時核心線程才會被回收;
  • maximumPoolSize:線程池中可以創建的最大線程數,限定為2^29-1;
  • keepAliveTime:當線程池中創建的線程超過了核心線程數的時候,在沒有新任務加入的等待時間;
  • workQueue:存放任務的隊列,只有當線程數 > 核心線程數,才會把其他的任務放入queue,一般常用的是queue就是ArrayBlockingQueue,LinkedBlockingQueue,SynchronousQueue;
  • threadFactory:創建線程的工廠類;
  • handler:當queue滿了和線程數達到最大限制,對于繼續到達的任務采取的策略。默認采取AbortPolicy , 也就是拒絕策略,直接拋出異常;

9、核心成員變量分析

  • 線程池中設計非常巧妙的一個地方是把線程池的狀態和運行的線程數量用一個int類型進行存儲;這樣一來可以保持線程池狀態和線程池活躍線程數量的一致性。因為AtomicInteger是線程安全的;
  • workerCount:線程池中當前活動的線程數量,占據ctl的低29位;
  • runState:線程池運行狀態,占據ctl的高3位,有RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED五種狀態;
  • 為了將線程池的狀態和線程池中的工作線程的數量放到一個int里面進行管理。他們利用了二進制數據進行位運算。其中int類型有4個字節,一個字節8位。總共有32位。其中高的3位表示線程的狀態。低29位代表線程的數量;

其中32位中,高三位代表的是狀態:

  1. 111 > RUNNING 
  2. 000 > SHUTDOWN 
  3. 001 > STOP 
  4. 010 > TIDYING 
  5. 110 > TERMINATED 

低29位代表線程的數量。所以最大的線程數為 2^29 -1 = 536870911;

// 記錄線程池狀態和線程數量(總共32位,前三位表示線程池狀態,后29位表示線程數量),保證線程安全性

  1. private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 
  2. // int 字節32位,COUNT_BITS代表的是29位 
  3.     private static final int COUNT_BITS = Integer.SIZE - 3; 
  4. // 線程的最大容量:000 11111111111111111111111111111 
  5.     private static final int CAPACITY   = (1 << COUNT_BITS) - 1; 
  6. // 運行狀態:111 00000000000000000000000000000 
  7.     private static final int RUNNING    = -1 << COUNT_BITS; 
  8. // 關閉狀態:000 00000000000000000000000000000 
  9.     private static final int SHUTDOWN   =  0 << COUNT_BITS; 
  10. // 停止狀態:001 00000000000000000000000000000 
  11.     private static final int STOP       =  1 << COUNT_BITS; 
  12. // 整理狀態:010 00000000000000000000000000000 
  13.     private static final int TIDYING    =  2 << COUNT_BITS; 
  14. // 終止狀態:011 00000000000000000000000000000 
  15.     private static final int TERMINATED =  3 << COUNT_BITS; 
  1. /** 
  2. * 是按位取反的意思,CAPACITY表示的是高位的3個0,和低位的29個1,而~CAPACITY則表示高位的3個1,2低位的9個0, 
  3. * 然后再與入參c執行按位與操作,即高3位保持原樣,低29位全部設置為0,也就獲取了線程池的運行狀態runState 
  4. */ 
  5.     private static int runStateOf(int c)     { return c & ~CAPACITY; } 
  6. /** 
  7. * 返回當前線程的數量。其中c代表線程池的狀態,即是高三位。: 
  8. * 而CAPACITY 代表的是線程的容量,即000 11111111111111111111111111111 
  9. * c & CAPACITY ,只有當都為1的時候,才為真,這樣直接舍棄高位 
  10. */ 
  11.     private static int workerCountOf(int c)  { return c & CAPACITY; } 
  12. /** 
  13. * 傳入的rs表示線程池運行狀態runState,其是高3位有值,低29位全部為0的int, 
  14. * 而wc則代表線程池中有效線程的數量workerCount,其為高3位全部為0,而低29位有值得int, 
  1. * 將runState和workerCount做或操作|處理,即用runState的高3位,workerCount的低29位填充的數字,而默認傳入的 
  2.  
  3. */ 
  4.     private static int ctlOf(int rs, int wc) { return rs | wc; } 

線程池的狀態轉換:

  1. // 調用了shutdown()方法  
  2. RUNNING -> SHUTDOWN  
  3. // 調用了shutdownNow()  
  4. (RUNNING 或 SHUTDOWN) -> STOP  
  5. // 當隊列和線程池為空  
  6. SHUTDOWN -> TIDYING  
  7. // 當線程池為空  
  8. STOP -> TIDYING  
  9. // 當terminated()鉤子方法執行完成  
  10. TIDYING -> TERMINATED  

二、線程池執行流程源碼分析

1、程序入口:execute 方法

  1. public void execute(Runnable command) { 
  2.    if (command == null
  3.        throw new NullPointerException(); 
  4.    //獲取當前線程池的狀態+線程個數變量 
  5.    int c = ctl.get(); 
  6.    //當前線程池線程個數是否小于corePoolSize,小于則開啟新線程運行 
  7.    if (workerCountOf(c) < corePoolSize) { 
  8.        if (addWorker(command, true)) 
  9.            return
  10.        c = ctl.get(); 
  11.    } 
  12.    //如果線程池處于RUNNING狀態,則添加任務到阻塞隊列 
  13.    if (isRunning(c) && workQueue.offer(command)) { 
  14.        //二次檢查 
  15.        int recheck = ctl.get(); 
  16.        //如果當前線程池狀態不是RUNNING則從隊列刪除任務,并執行拒絕策略 
  17.        if (! isRunning(recheck) && remove(command)) 
  18.            reject(command); 
  19.        //否者如果當前線程池線程空,則添加一個線程 
  20.        else if (workerCountOf(recheck) == 0) 
  21.            addWorker(nullfalse); 
  22.    } 
  23.    //如果隊列滿了,則新增線程,新增失敗則執行拒絕策略 
  24.    else if (!addWorker(command, false)) 
  25.        reject(command); 
  • 如果當前線程池線程個數小于corePoolSize則開啟新線程;
  • 否則添加任務到任務隊列;
  • 如果任務隊列滿了,則嘗試新開啟線程執行任務,如果線程個數>maximumPoolSize則執行拒絕策略;

重點看addWorkder方法:

  1. private boolean addWorker(Runnable firstTask, boolean core) { 
  2.    retry: 
  3.    for (;;) { 
  4.        int c = ctl.get(); 
  5.        int rs = runStateOf(c); 
  6.        //1、 檢查隊列是否只在必要時為空. 
  7.        if (rs >= SHUTDOWN && 
  8.            ! (rs == SHUTDOWN && 
  9.               firstTask == null && 
  10.               ! workQueue.isEmpty())) 
  11.            return false
  12.        //循環cas增加線程個數 
  13.        for (;;) { 
  14.            int wc = workerCountOf(c); 
  15.            //如果線程個數超限則返回false 
  16.            if (wc >= CAPACITY || 
  17.                wc >= (core ? corePoolSize : maximumPoolSize)) 
  18.                return false
  19.            //cas增加線程個數,同時只有一個線程成功 
  20.            if (compareAndIncrementWorkerCount(c)) 
  21.                break retry; 
  22.            //cas失敗了,則看線程池狀態是否變化了,變化則跳到外層循環重試重新獲取線程池狀態,否者內層循環重新cas。 
  23.            c = ctl.get();  // Re-read ctl 
  24.            if (runStateOf(c) != rs) 
  25.                continue retry; 
  26.        } 
  27.    } 
  28.    //2、到這里說明cas成功了 
  29.    boolean workerStarted = false
  30.    boolean workerAdded = false
  31.    Worker w = null
  32.    try { 
  33.        //創建worker 
  34.        final ReentrantLock mainLock = this.mainLock; 
  35.        w = new Worker(firstTask); 
  36.        final Thread t = w.thread; 
  37.        if (t != null) { 
  38.            //加獨占鎖,為了workers同步,因為可能多個線程調用了線程池的execute方法。 
  39.            mainLock.lock(); 
  40.            try { 
  41.                //重新檢查線程池狀態,為了避免在獲取鎖前調用了shutdown接口 
  42.                int c = ctl.get(); 
  43.                int rs = runStateOf(c); 
  44.                if (rs < SHUTDOWN || 
  45.                    (rs == SHUTDOWN && firstTask == null)) { 
  46.                    if (t.isAlive()) // precheck that t is startable 
  47.                        throw new IllegalThreadStateException(); 
  48.                    //添加任務 
  49.                    workers.add(w); 
  50.                    int s = workers.size(); 
  51.                    if (s > largestPoolSize) 
  52.                        largestPoolSize = s; 
  53.                    workerAdded = true
  54.                } 
  55.            } finally { 
  56.                mainLock.unlock(); 
  57.            } 
  58.            //添加成功則啟動任務 
  59.            if (workerAdded) { 
  60.                t.start(); 
  61.                workerStarted = true
  62.            } 
  63.        } 
  64.    } finally { 
  65.        if (! workerStarted) 
  66.            addWorkerFailed(w); 
  67.    } 
  68.    return workerStarted; 
  • 第(1)雙重循環目的是通過cas增加線程池線程個數;
  • 第(2)主要是并發安全的把任務添加到workers里面,并且啟動任務執行;
  1. rs >= SHUTDOWN && 
  2.               ! (rs == SHUTDOWN && 
  3.                   firstTask == null && 
  4.                   ! workQueue.isEmpty()) 

也就是說下面幾種情況下會返回false:

  • 當前線程池狀態為STOP,TIDYING,TERMINATED;
  • 當前線程池狀態為SHUTDOWN并且已經有了第一個任務;
  • 當前線程池狀態為SHUTDOWN并且任務隊列為空;
  • 內層循環作用是使用cas增加線程個數,如果線程個數超限則返回false,否者進行cas,cas成功則退出雙循環,否者cas失敗了,要看當前線程池的狀態是否變化了,如果變了,則重新進入外層循環重新獲取線程池狀態,否者進入內層循環繼續進行cas嘗試;
  • 到了第(2)說明CAS成功了,也就是說線程個數加一了,但是現在任務還沒開始執行,這里使用全局的獨占鎖來控制workers里面添加任務,其實也可以使用并發安全的set,但是性能沒有獨占鎖好;
  • 這里需要注意的是要在獲取鎖后重新檢查線程池的狀態,這是因為其他線程可可能在本方法獲取鎖前改變了線程池的狀態,比如調用了shutdown方法。添加成功則啟動任務執行;

2、 工作線程Worker

先看下構造函數:

  1. Worker(Runnable firstTask) { 
  2.    setState(-1); // 在調用runWorker前禁止中斷 
  3.    this.firstTask = firstTask; 
  4.    this.thread = getThreadFactory().newThread(this);//創建一個線程 
  • 這里添加一個新狀態-1是為了避免當前線程worker線程被中斷;
  • 這里設置了-1所以條件不滿足就不會中斷該線程了;
  • 運行runWorker時候會調用unlock方法,該方法吧status變為了0,所以這時候調用shutdownNow會中斷worker線程;
  1. final void runWorker(Worker w) { 
  2.        Thread wt = Thread.currentThread(); 
  3.        Runnable task = w.firstTask; 
  4.        w.firstTask = null
  5.        w.unlock(); // status設置為0,允許中斷 
  6.        boolean completedAbruptly = true
  7.        try { 
  8.            while (task != null || (task = getTask()) != null) { 
  9.                w.lock(); 
  10.                // 如果線程池當前狀態至少是stop,則設置中斷標志; 
  11.                // 如果線程池當前狀態是RUNNININ,則重置中斷標志,重置后需要重新 
  12.                //檢查下線程池狀態,因為當重置中斷標志時候,可能調用了線程池的shutdown方法 
  13.                //改變了線程池狀態。 
  14.                if ((runStateAtLeast(ctl.get(), STOP) || 
  15.                     (Thread.interrupted() && 
  16.                      runStateAtLeast(ctl.get(), STOP))) && 
  17.                    !wt.isInterrupted()) 
  18.                    wt.interrupt(); 
  19.                try { 
  20.                    //任務執行前干一些事情 
  21.                    beforeExecute(wt, task); 
  22.                    Throwable thrown = null
  23.                    try { 
  24.                        task.run();//執行任務 
  25.                    } catch (RuntimeException x) { 
  26.                        thrown = x; throw x; 
  27.                    } catch (Error x) { 
  28.                        thrown = x; throw x; 
  29.                    } catch (Throwable x) { 
  30.                        thrown = x; throw new Error(x); 
  31.                    } finally { 
  32.                        //任務執行完畢后干一些事情 
  33.                        afterExecute(task, thrown); 
  34.                    } 
  35.                } finally { 
  36.                    task = null
  37.                    //統計當前worker完成了多少個任務 
  38.                    w.completedTasks++; 
  39.                    w.unlock(); 
  40.                } 
  41.            } 
  42.            completedAbruptly = false
  43.        } finally { 
  44.            //執行清了工作 
  45.            processWorkerExit(w, completedAbruptly); 
  46.        } 
  47.    } 
  • 如果當前task為空,則直接執行;
  • 否者調用getTask從任務隊列獲取一個任務執行,如果任務隊列為空,則worker退出;
  1. private Runnable getTask() { 
  2.    boolean timedOut = false; // Did the last poll() time out
  3.    retry: 
  4.    for (;;) { 
  5.        int c = ctl.get(); 
  6.        int rs = runStateOf(c); 
  7.        // 如果當前線程池狀態>=STOP 或者線程池狀態為shutdown并且工作隊列為空則,減少工作線程個數 
  8.        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { 
  9.            decrementWorkerCount(); 
  10.            return null
  11.        } 
  12.        boolean timed;      // Are workers subject to culling? 
  13.        for (;;) { 
  14.            int wc = workerCountOf(c); 
  15.            timed = allowCoreThreadTimeOut || wc > corePoolSize; 
  16.            if (wc <= maximumPoolSize && ! (timedOut && timed)) 
  17.                break; 
  18.            if (compareAndDecrementWorkerCount(c)) 
  19.                return null
  20.            c = ctl.get();  // Re-read ctl 
  21.            if (runStateOf(c) != rs) 
  22.                continue retry; 
  23.            // else CAS failed due to workerCount change; retry inner loop 
  24.        } 
  25.        try { 
  26.            //根據timed選擇調用poll還是阻塞的take 
  27.            Runnable r = timed ? 
  28.                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : 
  29.                workQueue.take(); 
  30.            if (r != null
  31.                return r; 
  32.            timedOut = true
  33.        } catch (InterruptedException retry) { 
  34.            timedOut = false
  35.        } 
  36.    } 
  37. private void processWorkerExit(Worker w, boolean completedAbruptly) { 
  38.    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted 
  39.        decrementWorkerCount(); 
  40.    //統計整個線程池完成的任務個數 
  41.    final ReentrantLock mainLock = this.mainLock; 
  42.    mainLock.lock(); 
  43.    try { 
  44.        completedTaskCount += w.completedTasks; 
  45.        workers.remove(w); 
  46.    } finally { 
  47.        mainLock.unlock(); 
  48.    } 
  49.    //嘗試設置線程池狀態為TERMINATED,如果當前是shutdonw狀態并且工作隊列為空 
  50.    //或者當前是stop狀態當前線程池里面沒有活動線程 
  51.    tryTerminate(); 
  52.    //如果當前線程個數小于核心個數,則增加 
  53.    int c = ctl.get(); 
  54.    if (runStateLessThan(c, STOP)) { 
  55.        if (!completedAbruptly) { 
  56.            int min = allowCoreThreadTimeOut ? 0 : corePoolSize; 
  57.            if (min == 0 && ! workQueue.isEmpty()) 
  58.                min = 1; 
  59.            if (workerCountOf(c) >= min
  60.                return; // replacement not needed 
  61.        } 
  62.        addWorker(nullfalse); 
  63.    } 

3、 shutdown操作

  • 調用shutdown后,線程池就不會在接受新的任務了;
  • 但是工作隊列里面的任務還是要執行的,但是該方法立刻返回的,并不等待隊列任務完成在返回;
  1. public void shutdown() { 
  2.    final ReentrantLock mainLock = this.mainLock; 
  3.    mainLock.lock(); 
  4.    try { 
  5.        //權限檢查 
  6.        checkShutdownAccess(); 
  7.        //設置當前線程池狀態為SHUTDOWN,如果已經是SHUTDOWN則直接返回 
  8.        advanceRunState(SHUTDOWN); 
  9.        //設置中斷標志 
  10.        interruptIdleWorkers(); 
  11.        onShutdown(); // hook for ScheduledThreadPoolExecutor 
  12.    } finally { 
  13.        mainLock.unlock(); 
  14.    } 
  15.    //嘗試狀態變為TERMINATED 
  16.    tryTerminate(); 

如果當前狀態>=targetState則直接返回,否者設置當前狀態為targetState;

  1. private void advanceRunState(int targetState) { 
  2.    for (;;) { 
  3.        int c = ctl.get(); 
  4.        if (runStateAtLeast(c, targetState) || 
  5.            ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) 
  6.            break; 
  7.    } 
  8. private void interruptIdleWorkers() { 
  9.    interruptIdleWorkers(false); 
  • 設置所有線程的中斷標志,主要這里首先加了全局鎖;
  • 同時只有一個線程可以調用shutdown時候設置中斷標志,然后嘗試獲取worker自己的鎖,獲取成功則設置中斷標示;
  1. private void interruptIdleWorkers(boolean onlyOne) { 
  2.    final ReentrantLock mainLock = this.mainLock; 
  3.    mainLock.lock(); 
  4.    try { 
  5.        for (Worker w : workers) { 
  6.            Thread t = w.thread; 
  7.            if (!t.isInterrupted() && w.tryLock()) { 
  8.                try { 
  9.                    t.interrupt(); 
  10.                } catch (SecurityException ignore) { 
  11.                } finally { 
  12.                    w.unlock(); 
  13.                } 
  14.            } 
  15.            if (onlyOne) 
  16.                break; 
  17.        } 
  18.    } finally { 
  19.        mainLock.unlock(); 
  20.    } 

4、shutdownNow操作

調用shutdown后,線程池就不會在接受新的任務了,并且丟棄工作隊列里面里面的任務,正在執行的任務會被中斷,但是該方法立刻返回的,并不等待激活的任務執行完成在返回。返回隊列里面的任務列表;

  1. public List<Runnable> shutdownNow() { 
  2.    List<Runnable> tasks; 
  3.    final ReentrantLock mainLock = this.mainLock; 
  4.    mainLock.lock(); 
  5.    try { 
  6.        checkShutdownAccess();//權限檢查 
  7.        advanceRunState(STOP);// 設置線程池狀態為stop 
  8.        interruptWorkers();//中斷線程 
  9.        tasks = drainQueue();//移動隊列任務到tasks 
  10.    } finally { 
  11.        mainLock.unlock(); 
  12.    } 
  13.    tryTerminate(); 
  14.    return tasks; 
  • 調用隊列的drainTo一次當前隊列的元素到taskList;
  • 可能失敗,如果調用drainTo后隊列海不為空,則循環刪除,并添加到taskList;
  1. private List<Runnable> drainQueue() { 
  2.    BlockingQueue<Runnable> q = workQueue; 
  3.    List<Runnable> taskList = new ArrayList<Runnable>(); 
  4.    q.drainTo(taskList); 
  5.    if (!q.isEmpty()) { 
  6.        for (Runnable r : q.toArray(new Runnable[0])) { 
  7.            if (q.remove(r)) 
  8.                taskList.add(r); 
  9.        } 
  10.    } 
  11.    return taskList; 

5、 awaitTermination操作

  • 等待線程池狀態變為TERMINATED則返回,或者時間超時;
  • 由于整個過程獨占鎖,所以一般調用shutdown或者shutdownNow后使用;
  1. public boolean awaitTermination(long timeout, TimeUnit unit) 
  2.        throws InterruptedException { 
  3.        long nanos = unit.toNanos(timeout); 
  4.        final ReentrantLock mainLock = this.mainLock; 
  5.        mainLock.lock(); 
  6.        try { 
  7.            for (;;) { 
  8.                if (runStateAtLeast(ctl.get(), TERMINATED)) 
  9.                    return true
  10.                if (nanos <= 0) 
  11.                    return false
  12.                nanos = termination.awaitNanos(nanos); 
  13.            } 
  14.        } finally { 
  15.            mainLock.unlock(); 
  16.        } 
  17.    } 

總結

當往線程池中添加任務的時候,每次添加一個任務都回去新增一個線程。直到不滿足 wc < corePoolSize;

當前線程池的大小已經達到了corePoolSize的時候,每次添加任務會被存放到阻塞任務隊列中。等待執行;

等等待任務隊列也滿的時候,且添加失敗。此時在來新的任務,就會接著增加線程的個數,直到滿足:wc >= maximumPoolSize ,添加線程失敗執行拒絕策略;

線程池中,把線程的狀態和數量通過int類型進行維護,高三位表示狀態,低29位表示線程數量。這樣可以保證線程的狀態和數量的一致性;

線程池巧妙的使用一個Integer類型原子變量來記錄線程池狀態和線程池線程個數;

 

責任編輯:武曉燕 來源: Android開發編程
相關推薦

2020-12-10 08:24:40

線程池線程方法

2015-10-10 09:39:42

Java線程池源碼解析

2021-07-30 19:44:51

AndroidJava線程

2021-09-18 06:56:01

JavaCAS機制

2020-12-08 08:53:53

編程ThreadPoolE線程池

2025-09-24 18:39:45

2020-03-05 15:34:16

線程池C語言局域網

2020-07-08 12:05:55

Java線程池策略

2020-09-04 10:29:47

Java線程池并發

2012-05-15 02:18:31

Java線程池

2021-09-01 06:48:16

AndroidGlide緩存

2021-09-06 13:12:05

前端JavaScript編程

2023-11-29 16:38:12

線程池阻塞隊列開發

2013-05-23 15:59:00

線程池

2012-02-01 11:20:23

Java線程

2023-06-07 13:49:00

多線程編程C#

2024-11-21 07:00:00

線程池Java開發

2022-03-22 09:20:57

應用線程池技術

2021-07-16 11:35:20

Java線程池代碼

2024-07-15 08:20:24

點贊
收藏

51CTO技術棧公眾號

欧美伊人久久大香线蕉综合69| 成人丝袜视频网| 一区二区在线视频| 五月天视频在线观看| av网址在线播放| kk眼镜猥琐国模调教系列一区二区| 欧美性受xxxx黑人猛交| 成人性视频免费看| 精品欧美午夜寂寞影院| 91福利在线播放| www.男人天堂网| 国产黄色片在线观看| 国产成人av在线影院| 国产精品99久久久久久久久久久久| 小泽玛利亚一区二区免费| 精品国产乱子伦一区二区| 欧美视频完全免费看| 国产69精品久久久久久久| jyzzz在线观看视频| 成人高清在线视频| 国产综合香蕉五月婷在线| 日本三级一区二区| 亚洲一级毛片| 在线播放国产一区二区三区| 一级黄色电影片| 亚洲成a人片777777久久| 岛国av午夜精品| 特大黑人娇小亚洲女mp4| www.久久热.com| 久久婷婷综合激情| 国产手机精品在线| 99视频国产精品免费观看a| 另类国产ts人妖高潮视频| 欧美另类高清videos| 国产精品情侣呻吟对白视频| 亚欧洲精品视频在线观看| 日韩欧美第一区| 91小视频在线播放| 国产成人午夜性a一级毛片| 精品国产电影一区| 日韩极品视频在线观看| www.久久ai| 国产精品毛片a∨一区二区三区| 久久狠狠久久综合桃花| 欧美天堂在线视频| 懂色中文一区二区在线播放| 国产精品一区=区| 久久久蜜桃一区二区| 国产日产高清欧美一区二区三区| 欧美激情一二三| 欧美色图亚洲天堂| 欧美久久九九| 欧美精品激情在线| 欧美国产日韩综合| 国内在线观看一区二区三区| 欧美日韩国产成人| 久青草免费视频| 国产精品videosex极品| 欧美激情免费观看| 日韩精品人妻中文字幕| 亚洲激情综合| 国产69久久精品成人| 性无码专区无码| 美日韩精品视频| 国产精品扒开腿做| 中文在线最新版天堂| 久久国产三级精品| 91九色国产社区在线观看| 国产日韩免费视频| 国产成人午夜99999| 豆国产97在线| 无码国精品一区二区免费蜜桃| 99久久精品免费看| 欧美一区二区影视| 嫩草在线视频| 一区二区三区视频在线看| 国产va亚洲va在线va| √天堂8资源中文在线| 狠狠干狠狠久久| 男女啪啪网站视频| www一区二区三区| 精品国产电影一区二区| 亚洲综合自拍网| 欧美手机在线| 久久中文字幕国产| 91蜜桃视频在线观看| 日韩专区欧美专区| 亚洲综合色av| 午夜一区在线观看| 国产精品卡一卡二卡三| 欧美人与动牲交xxxxbbbb| 国产中文在线播放| 精品视频一区二区不卡| 永久av免费在线观看| 日韩成人av在线资源| 日韩小视频在线观看| 久久黄色免费网站| 日本美女视频一区二区| 俄罗斯精品一区二区| 国产福利电影在线| 亚洲综合自拍偷拍| www.超碰com| 亚洲国产欧美国产第一区| 精品丝袜一区二区三区| 国产极品美女在线| 男人天堂欧美日韩| aa日韩免费精品视频一| 免费人成在线观看网站| 亚洲免费观看高清完整版在线观看熊| 欧美不卡在线播放| 成人精品视频在线观看| 日韩激情视频在线| 久久久精品视频在线| 日韩av成人高清| 国产精品一区二区av| 香蕉视频在线播放| 欧美性极品xxxx娇小| 色黄视频免费看| 精品国产a一区二区三区v免费| 欧美日本国产在线| 一级片视频网站| 久久久精品国产免费观看同学| 无码人妻精品一区二区蜜桃百度| 亚洲成人短视频| 亚洲激情视频在线观看| 欧美成人777| 免费在线观看视频一区| 久草精品电影| www.超碰在线| 欧美sm极限捆绑bd| caoporn91| 久久99久久99小草精品免视看| 欧美一级片免费观看| 欧美激情护士| 精品国产乱子伦一区| 久久久精品视频免费观看| 蜜桃久久精品一区二区| 欧美日韩一区在线播放| 欧美aa在线| 精品国产1区2区3区| 精品欧美一区二区久久久久 | 超碰97人人做人人爱少妇| 黄色av网站免费观看| 久久综合九色综合97婷婷| 国产www免费| 欧美1区2区3| 久热精品视频在线观看| 国产精品毛片一区视频播| 国产精品二三区| 亚洲综合婷婷久久| 久久久综合色| 成人免费在线视频网站| 国精产品一区| 日韩亚洲欧美成人一区| 欧美成人精品激情在线视频| 韩国女主播成人在线| 做爰高潮hd色即是空| 国产一区精品二区| 色综合久久中文字幕综合网小说| 精品国产无码一区二区| 亚洲自拍偷拍综合| 日韩综合第一页| 在线一区欧美| 欧洲在线视频一区| www.26天天久久天堂| 久久精品视频va| a天堂视频在线| 亚洲国产一二三| av无码一区二区三区| 久久精品人人做人人爽电影蜜月| 欧洲精品码一区二区三区免费看| 国产精品高清乱码在线观看| 中文字幕日韩高清| 国产三级第一页| 亚洲第一福利视频在线| 醉酒壮男gay强迫野外xx| 日韩中文字幕区一区有砖一区| 天天久久人人| 视频一区日韩精品| 91精品国产色综合| av在线资源站| 日韩免费观看高清完整版 | 亚洲精品欧洲| 欧美激情第一页在线观看| 素人一区二区三区| 久久999免费视频| 日本福利片高清在线观看| 精品视频在线免费| 激情综合网五月婷婷| 国产日韩欧美麻豆| 无码人妻少妇色欲av一区二区| 99精品视频免费观看| 亚洲乱码一区二区三区| 一区二区在线免费播放| 国产成人高清激情视频在线观看| 秋霞影院午夜丰满少妇在线视频| 精品国产1区二区| 亚洲综合精品国产一区二区三区 | 69视频免费在线观看| 中文字幕亚洲综合久久菠萝蜜| 成人做爰www看视频软件| 日本成人在线不卡视频| 欧美一区二区视频在线播放| 九九亚洲视频| 99爱精品视频| 亚洲mmav| 97色在线播放视频| 成人福利网站| 国产香蕉97碰碰久久人人| 亚洲黄色在线观看视频| 欧美综合亚洲图片综合区| 日韩 国产 在线| |精品福利一区二区三区| 黄瓜视频污在线观看| 国产成人午夜高潮毛片| 中文字幕在线综合| 天堂va蜜桃一区二区三区| www.好吊操| 欧美国产三级| 一区视频二区视频| av一区二区在线观看| 久久草视频在线看| 午夜日韩影院| 91久久精品国产| 成人国产在线| 国产成人精品在线播放| 久草在线资源福利站| 欧美精品免费在线观看| 日本a级在线| 在线一区二区日韩| 国产最新视频在线观看| 亚洲福利视频网站| 国产 欧美 精品| 日韩欧美成人一区| 国产高清在线免费| 欧美二区在线观看| 一级黄色片网站| 欧美日韩亚洲综合一区 | 91精品国产综合久久久蜜臀粉嫩| 久久久久久无码午夜精品直播| 性做久久久久久免费观看欧美| 午夜写真片福利电影网| 亚洲欧美一区二区三区久本道91| 自拍偷拍第9页| 国产日产亚洲精品系列| 免费看黄色的视频| 久久久久久亚洲综合影院红桃| 极品白嫩丰满美女无套| 91丨porny丨户外露出| 亚洲欧美日本一区| 91亚洲精品久久久蜜桃| 自拍偷拍亚洲天堂| 欧美国产激情一区二区三区蜜月| 这里只有久久精品| 国产午夜精品美女毛片视频| 中国女人特级毛片| 亚洲国产高清aⅴ视频| 国产极品视频在线观看| 18成人在线观看| 欧美精品乱码视频一二专区| 亚洲国产视频在线| 国产 欧美 日韩 在线| 色天天综合色天天久久| 中文字幕第99页| 欧美妇女性影城| 成人激情四射网| 亚洲国产日韩欧美在线动漫 | 在线一区二区日韩| 国产成人l区| 欧美精品aaa| 中文字幕不卡三区视频| 国产精品久久激情| 精品国产亚洲一区二区三区在线| www 成人av com| 美女主播精品视频一二三四| 欧美日韩综合另类| 97人人精品| 日韩激情视频一区二区| 久久av最新网址| 99re精彩视频| 大美女一区二区三区| 精品人妻互换一区二区三区| 国产欧美日韩精品一区| 久久国产波多野结衣| 亚洲成人手机在线| 性色av一区二区三区四区| 日韩一区二区在线看| 日本亚洲一区| 欧美成人午夜激情视频| 中文在线аv在线| 成人免费看片视频| 日韩欧美中文字幕电影| 亚洲欧美日韩不卡一区二区三区| 欧美a级一区| www.色偷偷.com| 成人综合在线观看| av在线播放中文字幕| 亚洲一区自拍偷拍| 伊人免费在线观看| 亚洲精品久久久久久久久久久 | 久久久久久综合网天天| 视频在线日韩| 国产精品视频福利| 国产精品成人一区二区不卡| 大肉大捧一进一出好爽视频| 久久国产精品99精品国产| 欧类av怡春院| 亚洲免费观看在线观看| 中文永久免费观看| 精品在线小视频| 国产探花在线观看| 成人性教育视频在线观看| 九九在线高清精品视频| 久操网在线观看| 黄页网站大全一区二区| 亚洲av无码一区二区三区人| 亚洲线精品一区二区三区| 国产又粗又猛又黄| 亚洲视频自拍偷拍| 中文不卡1区2区3区| 国产精品免费在线播放| 亚洲蜜桃视频| wwwwwxxxx日本| 国产亚洲视频系列| 毛片基地在线观看| 欧美精品一区二区三区在线播放| 色开心亚洲综合| 国产精品久久网| 精品久久久久久久| 欧美日韩亚洲一二三| 99在线精品一区二区三区| 久久久久久久久久久97| 日韩一级在线观看| 国产福利视频在线| 91在线精品视频| 图片区亚洲欧美小说区| 国产精品自拍视频在线| 国产精品理论片| 91麻豆视频在线观看| 日韩网站免费观看| 亚洲欧美久久精品| 在线观看福利一区| 国产一区二区福利视频| 手机av在线看| 日韩一区二区三区视频| 中文字幕在线观看网站| 亚洲一区二区在线| 欧美色123| 手机在线成人av| 午夜精品一区二区三区免费视频| 亚洲不卡免费视频| 国产综合在线看| 少妇一区二区三区| 成年人在线看片| 国产性色一区二区| 中文字幕在线观看视频一区| 日韩中文字幕视频| 国产中文欧美日韩在线| 中国女人做爰视频| 成人激情动漫在线观看| 日韩精品――中文字幕| 亚洲欧美一区二区三区久久| 国产精品高清乱码在线观看| 亚洲视频在线二区| 国产成人在线网站| 圆产精品久久久久久久久久久| 精品亚洲夜色av98在线观看| 另类图片综合电影| 在线视频欧美一区| 国产精品1024久久| 日本中文在线播放| 国产亚洲在线播放| 欧州一区二区三区| 久久无码高潮喷水| 国产精品久久久久永久免费观看| 国产精品欧美激情在线| 久久久亚洲精选| 九九热爱视频精品视频| 久久精品久久99| 午夜av电影一区| 成人影视在线播放| 99精彩视频在线观看免费| 国产一区二区三区久久| 欧美丰满老妇熟乱xxxxyyy| 欧美一区二区三区在线观看| av在线理伦电影| 亚洲国产精品一区二区第一页 | 五月婷婷综合在线观看| 欧美视频在线一区| sis001亚洲原创区| 亚洲精品成人自拍| av在线播放不卡| 一区二区的视频| 国产91ⅴ在线精品免费观看| 久久视频国产| theav精尽人亡av| 69堂成人精品免费视频| 伊人久久在线| 四虎4hu永久免费入口| 国产清纯白嫩初高生在线观看91|