参数
有7个参数
corePoolSize 核心线程池大小,默认创建的线程个数
maximumPoolSize 线程池最大大小,线程最多创建的个数
keepAliveTime 当线程在这段时间内没有任务时,就销毁
timeUnit 时间单位
blockingQueue 当线程池中任务数量大于maximumPoolSize时,任务加入队列
threadFatory 提供线程的创建方式,可以在里面做一些手脚比如命名
rejectedExecutionHandler 当任务数量超过maximum + queue的容量之后采用的拒绝策略
RejectedExecutionHandler
首先看下接口
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
我们可以自己实现拒绝策略,当然JDK提供了4 种策略处理器
AbortPolicy
字面上就能看出来拒绝方式是直接丢弃,丢弃方式则是抛出异常。
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
/**
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
CallerRunsPolicy
如果线程池没有关闭,则让这个申请的任务线程去调用任务的run。名副其实谁调用谁执行。
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }
/**
* Executes task r in the caller's thread, unless the executor
* has been shut down, in which case the task is discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
DiscardOldestPolicy
把线程池队列中队头扔掉,也就是扔掉等待最久的任务。然后把新任务加入线程池
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardOldestPolicy} for the given executor.
*/
public DiscardOldestPolicy() { }
/**
* Obtains and ignores the next task that the executor
* would otherwise execute, if one is immediately available,
* and then retries execution of task r, unless the executor
* is shut down, in which case task r is instead discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
DiscardPolicy
丢弃原则,什么也不做。
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }
/**
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
线程池大小配置
首先获取CPU个数
Runtime.getRuntime().availableProcessors()
如果是计算密集型
线程个数 = CPU个数 + 1;
例如 8 核心 线程个数 = 8 + 1 = 9
如果是IO密集型,大部分线程都在IO阻塞中。
线程个数 = CPU个数 / 1 - 阻塞系数 其中阻塞系数0.8 ~ 0.9
例如 8 核心 线程个数 = 8 / *(1 - 0.9) = 80
也可以 CPU个数 * 2 = 8 * 2 = 16