java自帶的線程池方法
大小:0.3 MB 人氣:0 2017-09-27 需要積分:1
從上面使用線程池的例子來看,最主要就是兩步,構造ThreadPoolExecutor對象,然后每來一個任務,就調用ThreadPoolExecutor對象的execute方法。
1、ThreadPoolExecutor結構
ThreadPoolExecutor的主要結構及繼承關系如下圖所示:
主要成員變量:任務隊列——存放那些暫時無法執行的任務;工作線程池——存放當前啟用的所有線程;線程工廠——創建線程;還有一些用來調度線程與任務并保證線程安全的成員。
了解了ThreadPoolExecutor的主要結構,再簡單梳理一下“一個傳入線程池的任務能夠被最終正常執行需要經過的主要流程”,方法名稱前面沒有“XXX.”這種標注的都是ThreadPoolExecutor的方法:
2、ThreadPoolExecutor構造器及重要常量
簡單了解下構造器,ThreadPoolExecutor的四個構造器的源碼如下:
publicThreadPoolExecutor( intcorePoolSize, intmaximumPoolSize,longkeepAliveTime,TimeUnit unit,BlockingQueue《Runnable》 workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); }publicThreadPoolExecutor( intcorePoolSize, intmaximumPoolSize,longkeepAliveTime,TimeUnit unit,BlockingQueue《Runnable》 workQueue,ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,threadFactory, defaultHandler); } publicThreadPoolExecutor( intcorePoolSize,intmaximumPoolSize, longkeepAliveTime,TimeUnit unit,BlockingQueue《Runnable》 workQueue,RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), handler); }publicThreadPoolExecutor( intcorePoolSize, intmaximumPoolSize,longkeepAliveTime,TimeUnit unit,BlockingQueue《Runnable》 workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) { if(corePoolSize 《0||maximumPoolSize 《= 0||maximumPoolSize 《 corePoolSize ||keepAliveTime 《 0)thrownewIllegalArgumentException(); if(workQueue == null|| threadFactory == null|| handler == null) thrownewNullPointerException(); this.acc = System.getSecurityManager() == null? null:AccessController.getContext(); this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory;this.handler = handler; }
從源碼中可以看出,這四個構造器都是調用最后一個構造器,只是根據開發者傳入的參數的不同而填充一些默認的參數。比如如果開發者沒有傳入線程工廠threadFactory參數,那么構造器就使用默認的Executors.defaultThreadFactor。
在這里還要理解ThreadPoolExecutor的幾個常量的含義和幾個簡單方法:
//Integer.SIZE是一個靜態常量,值為32,也就是說COUNT_BITS是29privatestaticfinalintCOUNT_BITS = Integer.SIZE - 3; //CAPACITY是最大容量536870911,因為1左移29位之后-1,導致最高三位為0,而其余29位全部為1privatestaticfinalintCAPACITY = ( 1《《 COUNT_BITS) - 1; //ctl用于表示線程池狀態和有效線程數量,最高三位表示線程池的狀態,其余低位表示有效線程數量//初始化之后ctl等于RUNNING的值,即默認狀態是運行狀態,線程數量為0privatefinalAtomicInteger ctl =newAtomicInteger(ctlOf(RUNNING, 0)); //1110 0000 0000 0000 0000 0000 0000 0000最高三位為111privatestaticfinalintRUNNING = - 1《《 COUNT_BITS; //最高三位為000privatestaticfinalintSHUTDOWN = 0《《 COUNT_BITS; //0010 0000 0000 0000 0000 0000 0000 0000最高三位為001privatestaticfinalintSTOP = 1《《 COUNT_BITS; //0100 0000 0000 0000 0000 0000 0000 0000最高三位為010privatestaticfinalintTIDYING = 2《《 COUNT_BITS; //0110 0000 0000 0000 0000 0000 0000 0000最高三位為011privatestaticfinalintTERMINATED = 3《《 COUNT_BITS; /** * 獲取運行狀態,入參為ctl。因為CAPACITY是最高三位為0,其余低位為1 * 所以當取反的時候,就只有最高三位為1,再經過與運算,只會取到ctl的最高三位 * 而這最高三位如上文所述,表示線程池的狀態 */privatestaticintrunStateOf( intc) { returnc & ~CAPACITY; } /** * 獲取工作線程數量,入參為ctl。因為CAPACITY是最高三位為0,其余低位為1 * 所以當進行與運算的時候,只會取到低29位,這29位正好表示有效線程數量 */privatestaticintworkerCountOf( intc) { returnc & CAPACITY; } privatestaticintctlOf( intrs, intwc) { returnrs | wc; } //任務隊列,用于存放待執行任務的阻塞隊列privatefinalBlockingQueue《Runnable》 workQueue; /** 判斷線程池是否是運行狀態,傳入的參數是ctl的值 * 只有RUNNING的符號位是1,也就是只有RUNNING為負數 * 所以如果目前的ctl值《0,就是RUNNING狀態 */privatestaticbooleanisRunning(intc) { returnc 《 SHUTDOWN; } //從任務隊列中移除任務publicbooleanremove(Runnable task) { booleanremoved = workQueue.remove(task); tryTerminate(); // In case SHUTDOWN and now emptyreturnremoved; }
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%