1.线程池配置
public ThreadPoolExecutor(intcorePoolSize, //核心线程数
int maximumPoolSize, //最大线程数
long keepAliveTime,//空闲时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//等待队列
ThreadFactory threadFactory,//线程工厂
RejectedExecutionHandler handler) {//拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize <corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue ==null ||threadFactory ==null || handler == null)
throw new NullPointerException();
this.corePoolSize =corePoolSize;
this.maximumPoolSize =maximumPoolSize;
this.workQueue =workQueue;
this.keepAliveTime =unit.toNanos(keepAliveTime);
this.threadFactory =threadFactory;
this.handler =handler;
}
2.线程池执行过程
public void execute(Runnablecommand) {
if (command ==null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) <corePoolSize) {//初时线程数为0,小于核心线程数
if (addWorker(command,true))//为true,添加core核心线程,方法内部二次验证,做个标记
return;
c = ctl.get();
}
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);
}
else if (!addWorker(command,false))
reject(command);
}
3.线程池worker工作原理
final void runWorker(Workerw) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask =null;
w.unlock(); // allow interrupts
booleancompletedAbruptly =true;
try {
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 {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeExceptionx) {
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);
}
}
4.空闲线程回收原理
private Runnable getTask() {
booleantimedOut =false;// Did the last poll() time out?
retry:
for (;;) {
int c =ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >=SHUTDOWN && (rs >=STOP ||workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
booleantimed; // Are workers subject to culling?
for (;;) {
int wc = workerCountOf(c);
timed =allowCoreThreadTimeOut ||wc >corePoolSize;
if (wc <=maximumPoolSize && ! (timedOut &&timed))
break;
if (compareAndDecrementWorkerCount(c))
return null;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) !=rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r !=null)
return r;
timedOut =true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
5.空闲线程退出机制
private void processWorkerExit(Workerw,boolean completedAbruptly) {
if (completedAbruptly)// If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount +=w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
if (runStateLessThan(c,STOP)) {
if (!completedAbruptly) {
intmin =allowCoreThreadTimeOut ? 0 :corePoolSize;
if (min == 0 && !workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >=min)
return;// replacement not needed
}
addWorker(null,false);
}
}
6.定时线程池
schedule 执行一次
scheduleAtFixedRate 按照固定频率多次执行
scheduleWithFixedDelay 按照固定延时多次执行