public ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//非核心线程存活时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//阻塞队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler) {//拒绝策略
阻塞队列就是ThreadPoolExecutor中的 workQueue参数。
阻塞队列有:ArrayBlockingQueue(数组阻塞队列)、LinkedBlockingQueue(链表阻塞队列/无界队列)、SynchronousQueue(同步队列)、DelayedWorkQueue(延迟工作队列)
ArrayBlockingQueue
底层结构:静态数组,容量固定,没有扩容机制(不像ArrayList是动态数组),如果数组下标上没有内容就会有null填充。
用的是同一把锁
阻塞:出队列时,如果队列为空,就阻塞 notEmpty。入队列时,队列满了,就阻塞notFull。
入队列从队首加元素,记录putIndex,唤醒notEmpty
出队列从队首取元素,记录takeIndex,唤醒notFull
顺序:先进先出
LinkedBlockingQueue
数据结构:链表Node(next,prev…),可以指定容量,默认Integer.MAX_VALUE
有两把锁:取takeLock =new ReentrantLock(); 放putLock = new ReentrantLock();
读写分离,取时加takeLock,存时加putLock,删除时,两个锁一起加。
入队从队尾入队,记录last节点
出队从队首出队,记录head节点。
顺序:先进先出
拒绝策略
一种是直接抛异常,一种是直接丢弃任务,还有一种是抛弃等待最久的任务,另外一种我忘了。AbortPolicy 直接抛异常,程序中断。;CallerRunsPolicy 回退调用者
DiscardOldestPolicy 抛弃队列种等待最久的任务,尝试提交 DiscardPolicy 直接丢弃任务
使用:
具体使用要根据业务来,如果业务可以支持抛异常就用抛异常,如果任务可以丢弃就用丢弃策略,没有特定的方式。我看过一个框架重写的拒绝策略是什么都不处理,具体是哪个我忘了好像是apache