构造参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize -线程池中核心线程的数量
maximumPoolSize -线程池中最大线程数
keepAliveTime -当线程数大于核心,这是多余的空闲线程会等待新的任务终止前的最大时间
unit -keepAliveTime对应的时间单位
workQueue -工作队列。这个队列将只有 Runnable execute方法提交的任务
threadFactory -工厂用于执行创建新线程
handler -达到线程边界和队列容量,饱和策略
执行原理
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//ctl:AtomicInteger,代表线程执行状态,和worker集合数量
int c = ctl.get();
//worker集合中线程数小于核心线程数
if (workerCountOf(c) < corePoolSize) {
//加入当前任务线程到worker集合,true表示后期有个判断逻辑选择的是corePoolSize
if (addWorker(command, true))
return;
c = ctl.get();
}
//worker集合中线程数不小于核心线程数,且线程是运行状态,将当前线程加入队列中
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);
}
//worker集合中线程数等于核心线程数,且线程等待队列已满,但是线程数未达到最大线程数,则继续创建工作线程
//false表示后期有个判断逻辑选择的是maximumPoolSize
else if (!addWorker(command, false))
//worker集合中线程数等于核心线程数,且线程等待队列已满,且线程数也达到最大线程数,则执行拒绝策略
reject(command);
}
代码事例
public class ThreadHelpController {
public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2, 5, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(5), new MyPolicy());
public static void main(String[] args) {
for (int i = 0; i < 11; i++) {
int a = i;
Thread thread = new Thread(
() -> {
System.out.println(a);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
);
threadPoolExecutor.execute(thread);
}
/**
* 输出结果:
1个线程输出:线程池饱和了,拒绝你 5线程输出5个数字
另外5个线程在工作队列中,等10秒后执行
*/ }
public static class MyPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public MyPolicy() {
}
/**
* 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) {
System.out.println("线程池饱和了,拒绝你");
}
}
}