參考鏈接:https://blog.csdn.net/u012702547/article/details/52259529
場(chǎng)景:listview中的item加載圖片,通過(guò)new Thread開(kāi)啟線程請(qǐng)求網(wǎng)絡(luò)
使用new Thread()創(chuàng)建線程存在的問(wèn)題
- 針對(duì)每一個(gè)item都創(chuàng)建一個(gè)新線程,這樣會(huì)導(dǎo)致頻繁的創(chuàng)建線程,線程執(zhí)行完之后又被回收,又會(huì)導(dǎo)致頻繁的GC
- 這么多線程缺乏統(tǒng)一管理,各線程之間互相競(jìng)爭(zhēng),降低程序的運(yùn)行效率,手機(jī)頁(yè)面卡頓,甚至?xí)?dǎo)致程序崩潰
- 如果一個(gè)item滑出頁(yè)面,則要停止該item上圖片的加載,但是如果使用這種方式來(lái)創(chuàng)建線程,則無(wú)法實(shí)現(xiàn)線程停止執(zhí)行
使用線程池的好處
- 重用已經(jīng)創(chuàng)建的好的線程,避免頻繁創(chuàng)建進(jìn)而導(dǎo)致的頻繁GC
- 控制線程并發(fā)數(shù),合理使用系統(tǒng)資源,提高應(yīng)用性能
- 可以有效的控制線程的執(zhí)行,比如定時(shí)執(zhí)行,取消執(zhí)行等
Executor本身是一個(gè)接口
ThreadPoolExecutor Executor的實(shí)現(xiàn)類
/**
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
ThreadPoolExecutor構(gòu)造方法參數(shù)的解釋
corePoolSize
核心線程,即在線程池中保留的線程數(shù),即使它們處于空閑狀態(tài)也保留,除非設(shè)置了{(lán)@code allowCoreThreadTimeOut}
maximumPoolSize:
線程池中允許的最大線程數(shù)
keepAliveTime
非核心線程的超時(shí)時(shí)長(zhǎng),當(dāng)系統(tǒng)中非核心線程閑置時(shí)間超過(guò)keepAliveTime之后,則會(huì)被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut屬性設(shè)置為true,則該參數(shù)也表示核心線程的超時(shí)時(shí)長(zhǎng)
unit
參數(shù)的時(shí)間單位,有納秒、微秒、毫秒、秒、分、時(shí)、天等
workQueue
線程池中的任務(wù)隊(duì)列,該隊(duì)列主要用來(lái)存儲(chǔ)已經(jīng)被提交但是尚未執(zhí)行的任務(wù)。存儲(chǔ)在這里的任務(wù)是由ThreadPoolExecutor的execute方法提交來(lái)的。
workQueue是一個(gè)BlockingQueue類型,是一個(gè)特殊的隊(duì)列,當(dāng)我們從BlockingQueue中取數(shù)據(jù)時(shí),如果BlockingQueue是空的,則取數(shù)據(jù)的操作會(huì)進(jìn)入到阻塞狀態(tài),當(dāng)BlockingQueue中有了新數(shù)據(jù)時(shí),這個(gè)取數(shù)據(jù)的操作又會(huì)被重新喚醒。同理,如果BlockingQueue中的數(shù)據(jù)已經(jīng)滿了,往BlockingQueue中存數(shù)據(jù)的操作又會(huì)進(jìn)入阻塞狀態(tài),直到BlockingQueue中又有新的空間,存數(shù)據(jù)的操作又會(huì)被沖洗喚醒。
threadFactory
在執(zhí)行時(shí)使用,為線程池提供創(chuàng)建新線程的功能,這個(gè)我們一般使用默認(rèn)即可
handler
拒絕策略,當(dāng)線程無(wú)法執(zhí)行新任務(wù)時(shí)(一般是由于線程池中的線程數(shù)量已經(jīng)達(dá)到最大數(shù)或者線程池關(guān)閉導(dǎo)致的),默認(rèn)情況下,當(dāng)線程池?zé)o法處理新線程時(shí),會(huì)拋出一個(gè)RejectedExecutionException。
線程提交到線程池之后運(yùn)行規(guī)則,遵循如下規(guī)則:
- 1.execute一個(gè)線程之后,如果線程池中的線程數(shù)未達(dá)到核心線程數(shù),則會(huì)立馬啟用一個(gè)核心線程去執(zhí)行
- 2.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)達(dá)到核心線程數(shù),且workQueue未滿,則將新線程放入workQueue中等待執(zhí)行
- 3.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)達(dá)到核心線程數(shù)但未超過(guò)非核心線程數(shù),且workQueue已滿,則開(kāi)啟一個(gè)非核心線程來(lái)執(zhí)行任務(wù)
- 4.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)超過(guò)非核心線程數(shù),則拒絕執(zhí)行該任務(wù)