Executors工具类默认提供了五种创建线程池的方法 分别是:
ThreadPoolExecutor类核心参数:
int corePoolSize, 核心线程数
int maximumPoolSize, 最大线程数
long keepAliveTime, 超时时间
TimeUnit unit, 单位
BlockingQueue<Runnable> workQueue, 任务队列(无界、有界)
ThreadFactory threadFactory, 线程工厂
RejectedExecutionHandler handler 新增失败后拒绝策略
Executors类核心方法:
newFixedThreadPool(【核心线程数量】) 设置固定核心线程数量 【缺点】队列无界
newCachedThreadPool() 设置不定长非核心线程数量 【缺点】 线程无界
newSingleThreadExecutor() 设置一个核心线程 【缺点】队列无界
newScheduledThreadPool(【核心线程数量】) 【缺点】线程无界
向线程池提交策略: 1、创建核心线程 2、任务队列 3、非核心线程 。全部满执行拒绝策略 默认执行 失败类AbortPolicy
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//1、运行线程数量少于corePoolSize尝试创建线程
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//2、如何任务排队成功,需要再次尝试检查石佛应该添加线程
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false); }
//3、如果无法添加到队列中,则创建新的线程,如果创建失败,则会走失拒绝策略
else if (!addWorker(command, false)) reject(command); }
线程池执行任务顺序 1、核心线程 2、非核心线程 3、队列
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
// allow interrupts
boolean completedAbruptly = true;
try {
//核心执行流程优先级 task != null 线程为空之后才进行取队列中的任务
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted())
wt.interrupt();
try {
//此时的task 对象不一样,可能是我们传进来的对象或者是 有返回值的task
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally { afterExecute(task, thrown); }
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//该方法内和核心实现了线程复用
processWorkerExit(w, completedAbruptly);
}
}
面试题:超出的核心线程何时销毁?
有一个重要的成员:keepAliveTime,当线程池里面的线程数量超过corePoolSize了,那么超出的线程将会在空闲keepAliveTime之后被terminated。可以参考下面的文档:
* If the pool currently has more than corePoolSize threads,
* excess threads will be terminated if they have been idle for more
* than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).
带有返回值的线程池执行对象: 实现Callable类 使用 Future类调用get方法进行接收