為什么要使用線程池?
隨著線程數(shù)量不斷的增多,會(huì)導(dǎo)致系統(tǒng)資源占用和內(nèi)存占用大,此時(shí)的線程需要一個(gè)類來(lái)統(tǒng)一管理,有次誕生了線程池。
線程池有兩個(gè)解決思路。
首先,針對(duì)反復(fù)創(chuàng)建線程開銷大的問(wèn)題,線程池用一些固定的線程一直保持工作狀態(tài)并反復(fù)執(zhí)行任務(wù)。
其次,針對(duì)過(guò)多線程占用太多內(nèi)存資源的問(wèn)題,解決思路更直接,線程池會(huì)根據(jù)需要?jiǎng)?chuàng)建線程,控制線程的總數(shù)量,避免占用過(guò)多內(nèi)存資源。
/**
* 描述: 用固定線程數(shù)的線程池執(zhí)行10000個(gè)任務(wù)
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10000; i++) {
service.execute(new Task());
}
System.out.println(Thread.currentThread().getName());
}
static class Task implements Runnable {
public void run() {
System.out.println("Thread Name: " + Thread.currentThread().getName());
}
}
}
使用線程池比手動(dòng)創(chuàng)建線程主要有三點(diǎn)好處。
第一點(diǎn),線程池可以解決線程生命周期的系統(tǒng)開銷問(wèn)題,同時(shí)還可以加快響應(yīng)速度。因?yàn)榫€程池中的線程是可以復(fù)用的,我們只用少量的線程去執(zhí)行大量的任務(wù),這就大大減小了線程生命周期的開銷。而且線程通常不是等接到任務(wù)后再臨時(shí)創(chuàng)建,而是已經(jīng)創(chuàng)建好時(shí)刻準(zhǔn)備執(zhí)行任務(wù),這樣就消除了線程創(chuàng)建所帶來(lái)的延遲,提升了響應(yīng)速度,增強(qiáng)了用戶體驗(yàn)。
第二點(diǎn),線程池可以統(tǒng)籌內(nèi)存和 CPU 的使用,避免資源使用不當(dāng)。線程池會(huì)根據(jù)配置和任務(wù)數(shù)量靈活地控制線程數(shù)量,不夠的時(shí)候就創(chuàng)建,太多的時(shí)候就回收,避免線程過(guò)多導(dǎo)致內(nèi)存溢出,或線程太少導(dǎo)致 CPU 資源浪費(fèi),達(dá)到了一個(gè)完美的平衡。
第三點(diǎn),線程池可以統(tǒng)一管理資源。比如線程池可以統(tǒng)一管理任務(wù)隊(duì)列和線程,可以統(tǒng)一開始或結(jié)束任務(wù),比單個(gè)線程逐一處理任務(wù)要更方便、更易于管理,同時(shí)也有利于數(shù)據(jù)統(tǒng)計(jì),比如我們可以很方便地統(tǒng)計(jì)出已經(jīng)執(zhí)行過(guò)的任務(wù)的數(shù)量。