您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Java中線程池的內(nèi)部原理分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
先看一下ThreadPoolExecutor類的execute方法:
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); //獲取clt,clt記錄著線程池狀態(tài)和運行線程數(shù)。 int c = ctl.get(); //運行線程數(shù)小于核心線程數(shù)時,創(chuàng)建線程放入線程池中,并且運行當前任務。 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; //創(chuàng)建線程失敗,重新獲取clt。 c = ctl.get(); } //線程池是運行狀態(tài)并且運行線程大于核心線程數(shù)時,把任務放入隊列中。 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); //重新檢查線程池不是運行狀態(tài)時, //把任務移除隊列,并通過拒絕策略對該任務進行處理。 if (! isRunning(recheck) && remove(command)) reject(command); //當前運行線程數(shù)為0時,創(chuàng)建線程加入線程池中。 else if (workerCountOf(recheck) == 0) addWorker(null, false); } //運行線程大于核心線程數(shù)時并且隊列已滿時, //創(chuàng)建線程放入線程池中,并且運行當前任務。 else if (!addWorker(command, false)) //運行線程大于最大線程數(shù)時,失敗則拒絕該任務 reject(command); }
在execute方法中,多次調(diào)用的addWorker方法,再看一下這個方法:
private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { //獲取clt,clt記錄著線程池狀態(tài)和運行線程數(shù)。 int c = ctl.get(); //獲取線程池的運行狀態(tài)。 int rs = runStateOf(c); //線程池處于關閉狀態(tài),或者當前任務為null //或者隊列不為空,則直接返回失敗。 if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; for (;;) { //獲取線程池中的線程數(shù) int wc = workerCountOf(c); //線程數(shù)超過CAPACITY,則返回false; //這里的core是addWorker方法的第二個參數(shù), //如果為true則根據(jù)核心線程數(shù)進行比較, //如果為false則根據(jù)最大線程數(shù)進行比較。 if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; //嘗試增加線程數(shù),如果成功,則跳出第一個for循環(huán) if (compareAndIncrementWorkerCount(c)) break retry; //如果增加線程數(shù)失敗,則重新獲取ctl c = ctl.get(); //如果當前的運行狀態(tài)不等于rs,說明狀態(tài)已被改變, //返回第一個for循環(huán)繼續(xù)執(zhí)行 if (runStateOf(c) != rs) continue retry; } } boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { //根據(jù)當前任務來創(chuàng)建Worker對象 w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //獲得鎖以后,重新檢查線程池狀態(tài) int rs = runStateOf(ctl.get()); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) throw new IllegalThreadStateException(); //把剛剛創(chuàng)建的線程加入到線程池中 workers.add(w); int s = workers.size(); //記錄線程池中出現(xiàn)過的最大線程數(shù)量 if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) { //啟動線程,開始運行任務 t.start(); workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }
關于“Java中線程池的內(nèi)部原理分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。