java線程池深入一

一.目的
多線程並行,提升效率,線程重用,減少創建線程開銷。

二.基礎知識
線程池幾個核心要素:
1.核心線程數
當有新的任務進來時,若沒有超過這個核心線程數,則會創建新的線程來執行任務。
2.最大線程數
用於限制最多可創建的線程,若超過這個值,默認的策略的拋異常。

3.線程超時時間
當已有線程數超過核心線程數時,超過這個時間,多於核心線程數的線程會被回收釋放。

4.隊列
用於存儲任務。

三.基礎流程
假設,當前核心線程數爲2,最大線程數是4,線程超時時間是1分鐘,隊列使用LinkedBlockingQueue大小爲10000。
拒絕策略是使任務提交者阻塞。

當任務提交者提交任務時,流程如下:



二.如何使用
一般有以下幾種用法:
1.通過Executos工具類創建線程池
固定線程數的線程池
ExecutorService executorService=Executors.newFixedThreadPool(10);
executorService.submit(new Runnable() {
public void run() {
System.out.println("hi");
}
});

//緩存線程的線程池
ExecutorService cacheExecutorService = Executors.newCachedThreadPool();
cacheExecutorService.execute(new Runnable() {
public void run() {
System.out.println("cached");
}
});


考慮下這兩種線程池有什麼問題?

2.直接通過new ThreadPoolExecutor
項目使用中,我們更多的是直接用ThreadPoolExecutor進行個性化定製。
一般我們會設置核心線程數,最大線程數,任務隊列最大數,有些時候如果是後臺任務則設置允許核心線程也能被回收。
代碼如下:
ExecutorService threadPoolExecutor = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1), new WaitRejctHandler());
threadPoolExecutor.allowCoreThreadTimeOut(true);

threadPoolExecutor.execute(new Runnable() {
public void run() {
System.out.println("threadPoolExecutor1");
}
});

static class WaitRejctHandler implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

三.存在哪些坑
在第二點如何使用上,Executors提供了方便創建FixedThreadPool及CachedThreadPool兩種線程池。
這兩種線程在生產者提交任務數過快時,FixedThreadPool會OOM,CachedThreadPool會導致線程數不斷增加最終也會導致OOM。
FixedThreadPool底層,核心線程數等於最大線程數(具體線程多少是入參決定),用的是無界LinkedBlockingQueue。
CachedThreadPool底層,核心線程數是0,最大線程數是Integer的MaxValue相當於無限多。而隊列使用的SyncronusQueue。
在CachedThreadPool應用場景,SyncronusQueue內部不會存儲任何任務。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章