這篇文章主要是摘抄再加上自己的理解,是為了加深自己的印象,詳情請(qǐng)查看:http://blog.csdn.net/u010687392/article/details/49850803,感謝作者提供的優(yōu)質(zhì)文章。
說(shuō)到線程池,要先說(shuō)線程,我們什么時(shí)候要用到線程呢?多線程一般應(yīng)用在處理耗時(shí)的操作,例如請(qǐng)求數(shù)據(jù),壓縮圖片,復(fù)雜的邏輯處理等等。
實(shí)現(xiàn)多線程一般有兩種方法:
1.繼承Thread類
2.實(shí)現(xiàn)Runnable接口
這兩種方法的主要區(qū)別:多線程訪問(wèn)同一資源的情況下,用Runnable接口創(chuàng)建的線程可以處理同一資源,而用Thread類創(chuàng)建的線程則各自獨(dú)立處理,各自擁有自己的資源。
所以Java中大多數(shù)多線程都是實(shí)現(xiàn)Runnable來(lái)完成,另外一個(gè)原因是Java中只可以單繼承,所以我們用實(shí)現(xiàn)接口來(lái)提高擴(kuò)展性。
new Thread(new Runnable() {
@Override
public void run() {
//邏輯處理
}
}).start();
上面的代碼創(chuàng)建了一個(gè)線程并執(zhí)行,在任務(wù)結(jié)束后GC會(huì)自動(dòng)回收該線程,但是這樣只能適用于線程并發(fā)不多的程序,不適用與需要開(kāi)啟大量線程來(lái)處理,會(huì)有如下影響:
1.線程的創(chuàng)建和銷毀都需要時(shí)間,當(dāng)有大量的線程創(chuàng)建和銷毀時(shí),會(huì)消耗很多時(shí)間將導(dǎo)致性能下降。
2.大量的線程創(chuàng)建,執(zhí)行和銷毀的非常消耗cup和內(nèi)存,止癢將直接影響系統(tǒng)的吞吐量,導(dǎo)致性能急劇下降,如果內(nèi)存資源占用的比較多,還可能造成OOM。
3.大量的線程的創(chuàng)建和銷毀很容易導(dǎo)致GC頻繁的執(zhí)行,從而發(fā)生內(nèi)存抖動(dòng)現(xiàn)象,會(huì)導(dǎo)致界面的卡頓。
為了解決這個(gè)問(wèn)題就引出了線程池(ExecutorService)概念,線程池的基本作用就是進(jìn)行線程的復(fù)用,減少線程的創(chuàng)建。
使用線程池管理線程的優(yōu)點(diǎn):
1.線程的創(chuàng)建和銷毀由線程池維護(hù),一個(gè)線程在完成任務(wù)后并不會(huì)立即銷毀,而是由后續(xù)的任務(wù)復(fù)用這個(gè)線程,從而減少線程的創(chuàng)建和銷毀,節(jié)約系統(tǒng)的開(kāi)銷。
2.線程池的本質(zhì)就是線程的復(fù)用,這樣可以節(jié)約我們創(chuàng)建和銷毀線程的時(shí)間,減少線程頻繁調(diào)度的開(kāi)銷,從而節(jié)約系統(tǒng)資源,提供系統(tǒng)吞吐量。
3.在執(zhí)行大量異步任務(wù)時(shí)提高了性能。
4.Java內(nèi)置一套ExecutorService線程池相關(guān)的api,可以更方便的控制線程的最大并發(fā)數(shù),線程的定時(shí)任務(wù),單線程的順序執(zhí)行等。
官方推薦使用Executors的工廠方法來(lái)創(chuàng)建線程池,Executors類是官方提供的一個(gè)工廠類,它里面封裝好了眾多功能不一樣的線程池。主要提供下面五種功能不一樣的線程池:
1.newFixedThreadPool():返回一個(gè)固定線程數(shù)的線程池,該線程池中的線程數(shù)量始終不變,不會(huì)在創(chuàng)建也不會(huì)銷毀已經(jīng)創(chuàng)建好的線程,自始至終都是那幾個(gè)固定的線程工作,所以該線程池可以控制線程的最大并發(fā)數(shù)。
2.newCachedThreadPool():返回一個(gè)可以根據(jù)實(shí)際情況調(diào)整線程池中線程數(shù)量的線程池。線程數(shù)量不確定,根據(jù)實(shí)際情況動(dòng)態(tài)調(diào)整。
舉例:假如該線程池中的所有線程都在工作,此時(shí)有新人物提交,那么將會(huì)創(chuàng)建新的線程去處理該任務(wù);如果此時(shí)之前的一些線程完成了任務(wù),現(xiàn)在又有新任務(wù)提交,那么將不會(huì)創(chuàng)建新線程去處理,而是復(fù)用空閑的線程去處理新任務(wù)。因?yàn)榫€程池中有一個(gè)“保持活動(dòng)時(shí)間”的參數(shù),通過(guò)配置它,如果線程池中的空閑線程的空閑時(shí)間超過(guò)該“保存活動(dòng)時(shí)間”則立即停止該線程,而該值默認(rèn)為60s。