之前又一次面試井厌,面試官問我線程池的大小,定義里面的線程數(shù)量多少最合適致讥。我當(dāng)時的回答是和CPU 核數(shù)有關(guān)仅仆,大概是 n+1 的關(guān)系。當(dāng)時看面試官反應(yīng)垢袱,可能沒答對墓拜。回來后请契,立即查詢線程池的相關(guān)資料咳榜。
一般說來夏醉,大家認(rèn)為線程池的大小經(jīng)驗值應(yīng)該這樣設(shè)置:(其中N為CPU的核數(shù))
如果是CPU密集型應(yīng)用,則線程池大小設(shè)置為N+1
如果是IO密集型應(yīng)用涌韩,則線程池大小設(shè)置為2N+1
那么我們的 Android 應(yīng)用是屬于哪一種應(yīng)用呢畔柔?看下他們的定義。
I/O密集型
I/O bound 指的是系統(tǒng)的CPU效能相對硬盤/內(nèi)存的效能要好很多臣樱,此時靶擦,系統(tǒng)運作,大部分的狀況是 CPU 在等 I/O (硬盤/內(nèi)存) 的讀/寫雇毫,此時 CPU Loading 不高玄捕。
CPU-bound
CPU bound 指的是系統(tǒng)的 硬盤/內(nèi)存 效能 相對 CPU 的效能 要好很多,此時嘴拢,系統(tǒng)運作桩盲,大部分的狀況是 CPU Loading 100%,CPU 要讀/寫 I/O (硬盤/內(nèi)存)席吴,I/O在很短的時間就可以完成赌结,而 CPU 還有許多運算要處理,CPU Loading 很高孝冒。
我們的Android 應(yīng)用的話應(yīng)該是屬于IO密集型應(yīng)用柬姚,所以數(shù)量一般設(shè)置為 2N+1。下面的例子是我截取的一段線程池創(chuàng)建的代碼:
private void ThreadPoolManager() {
//參數(shù)初始化
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心線程數(shù)量大小
private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//線程池最大容納線程數(shù)
private static final int maximumPoolSize = CPU_COUNT * 2 + 1;
//線程空閑后的存活時長
private static final int keepAliveTime = 30;
//任務(wù)過多后庄涡,存儲任務(wù)的一個阻塞隊列
BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
//線程的創(chuàng)建工廠
ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AdvacnedAsyncTask #" + mCount.getAndIncrement());
}
};
//線程池任務(wù)滿載后采取的任務(wù)拒絕策略
RejectedExecutionHandler rejectHandler = new ThreadPoolExecutor.DiscardOldestPolicy();
//線程池對象量承,創(chuàng)建線程
ThreadPoolExecutor mExecute = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
workQueue,
threadFactory,
rejectHandler
);
}