int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue,
new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
//執行任務
executorService.execute(new Runnnable() {
...
});
避免使用:
new Thread(new Runnable() {
@Override
public void run() {
//操作語句
...
}
}).start();
避免使用匿名內部類。不利於線程回收,銷燬,創建
建議使用線程池。 但是關於線程池創建配置,有一些疑慮:
引用別人說的話:
對於CPU密集型計算,多線程本質上是提升多核CPU的利用率,所以對於一個4核的CPU,每個核一個線程,理論上創建4個線程就可以了,再多創建線程也只是增加線程切換的成本。所以,對於CPU密集型的計算場景,理論上“線程的數量=CPU核數”就是最合適的。不過在工程上,線程的數量一般會設置爲“CPU核數+1”,這樣的話,當線程因爲偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證CPU的利用率。
此處附上本人設計的線程池工具類
public class ThreadPoolUtil {
/**
* CPU核心數
*/
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
/**
* 核心線程數,會一直存活,即使沒有任務,線程池也會維護線程的最少數量
*/
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
/**
* 線程池維護線程的最大數量
*/
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
/**
* 線程池維護線程所允許的空閒時間
*/
private static final int KEEP_ALIVE_SECONDS = 30;
/**
*線程池維護線程所允許的空閒時間單位
*/
private static final TimeUnit UNIT = TimeUnit.SECONDS;
/**
* 線程工廠,爲線程池提供創建新線程的功能
*/
private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "ChangeMax Thread #" + mCount.getAndIncrement());
}
};
/**
* 線程池中的任務隊列,通過線程池的execute方法提交的Runnable對象會存儲在這個參數中
*/
private static final BlockingQueue<Runnable> TASK_QUEUE = new LinkedBlockingQueue<>(128);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
private static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, UNIT,
TASK_QUEUE, THREAD_FACTORY);
//當設置allowCoreThreadTimeOut(true)時,線程池中"CORE_POOL_SIZE"線程空閒時間達到keepAliveTime也將關閉
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
public static Executor getPool() {
return THREAD_POOL_EXECUTOR;
}
}