构造方法
public ThreadPoolExecutor(int corePoolSize, // 核心线程数量
int maximumPoolSize,// 最大线程数量
long keepAliveTime,// (Max-Core)线程存活时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
看源码(jdk11): java/util/concurrent/ThreadPoolExecutor.java 第1318行
workQueue
一共有七种
SynchronousQueue
SynchronousQueue可以认为是一个缓存值为1的阻塞队列,但是 **isEmpty()**方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null。具体看源码。
// 构造方法有两个,默认是非公平模式
public SynchronousQueue(boolean fair) {
transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
一个是TransferStack类,使用LIFO顺序存储元素,这个类用于非公平模式;还有一个类是TransferQueue,使用FIFI顺序存储元素,这个类用于公平模式。 具体可参考这个链接:简书
LinkedBlockingQueue
不指定容量的话就是无界队列(Integer.MAX_VALUE,约等于无界了)。注意点:1-当可以保证线程池的数据<CoreNumber的时候,是可以提升一定的性能。但是代价是牺牲内存,可能OOM。慎用无参构造。
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
该类的大致结构
具体内容,可参考https://www.jianshu.com/p/9394b257fdde
ArrayBlockingQueue
有界队列,基于数组实现。在线程池初始化时,指定队列的容量。内部采用显式锁,两个锁条件。
PriorityBlockingQueue
支持优先级排序的无界阻塞队列。默认队列容量11。
Object[] queue; 队列元素数组。平衡二叉堆实现,父节点下标是n,左节点则是2n+1,右节点是2n+2。最小的元素在最前面。
ALLOCATIONSPINLOCK:allocationSpinLock:扩容数组分配资源时的自旋锁,CAS需要
// VarHandle mechanics
private static final VarHandle ALLOCATIONSPINLOCK;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
ALLOCATIONSPINLOCK = l.findVarHandle(PriorityBlockingQueue.class,
"allocationSpinLock",
int.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
// 排序器若是不传,则默认是自然排序。元素E,必须实现Comparable
public PriorityBlockingQueue(int initialCapacity,
Comparator<? super E> comparator) {
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.comparator = comparator;
this.queue = new Object[Math.max(1, initialCapacity)];
}
DelayQueue
延迟队列。
DelayQueue延迟队列同时具备:无界队列、阻塞队列、优先队列的特征。分别来看下:
无界队列:通过调用DelayQueue的offer方法(或add方法),把待执行的任务对象放入队列,该方法是非阻塞的。这个队列是无界队列,内存足够的情况下,理论上存放的任务对象数是无限的。
阻塞队列:DelayQueue实现了BlockingQueue接口,是一个阻塞队列。但该队列只是在取对象时阻塞,对应两个方法:1、take()方法,获取并移除队列头的对象,如果时间还未到,就阻塞等待。2、poll(long timeout, TimeUnit unit) 方法,阻塞时间长度为timeout,然后获取并移除队列头的对象,如果对象延迟时间还未到,就返回null。
优先队列:DelayQueue的一个重要的成员是一个优先队列PriorityQueue,PriorityQueue内部是一个二叉小顶堆实现,其特点就是头部元素对应的权值是队列中最小的,也就是通过poll()方法获取到的对象是最优先的。
ThreadFactory
默认的线程工厂代码如下
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
拒绝策略
当线程池workQueue已满且无法再创建新线程池时,就要拒绝后续任务了
AbortPolicy-默认
若此拒绝策略工作总会抛出:RejectedExecutionException。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
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) {
}