了解下JUC的线程池学习十三
1.介紹
线程池本身提供了大量数据统计相关的方法、扩容方法、预创建方法等等。
2.核心线程相关
getCorePoolSize()
:获取核心线程数。
setCorePoolSize()
:重新设置线程池的核心线程数。
prestartCoreThread()
:预启动一个核心线程,当且仅当工作线程数量小于核心线程数量。
prestartAllCoreThreads()
:预启动所有核心线程。
3.线程池容量相关
getMaximumPoolSize()
:获取线程池容量。
setMaximumPoolSize()
:重新设置线程池的最大容量。
4.线程存活周期相关
setKeepAliveTime()
:设置空闲工作线程的存活周期
getKeepAliveTime()
:获取空闲工作线程的存活周期。
5.监控统计相关方法
getTaskCount()
:获取所有已经被执行的任务总数的近似值。
getCompletedTaskCount()
:获取所有已经执行完成的任务总数的近似值。
getLargestPoolSize()
:获取线程池的峰值线程数(最大池容量)。
getActiveCount()
:获取所有活跃线程总数(正在执行任务的工作线程)的近似值。
getPoolSize()
:获取工作线程集合的容量(当前线程池中的总工作线程数)。
6.任务队列操作相关方法
purge()
:移除任务队列中所有是Future
类型并且已经处于Cancelled
状态的任务。
remove()
:从任务队列中移除指定的任务。
BlockingQueue<Runnable> getQueue()
:获取任务队列的引用。
7.ThreadPoolExecutor#setCorePoolSize()對worker的影响
有部分属性值的设置有可能影响到线程池中的状态或者工作线程的增减等,
例如核心线程数改变,有可能会直接增减Worker
,
这里就以ThreadPoolExecutor#setCorePoolSize()
为例:
// 设置核心线程数量
public void setCorePoolSize(int corePoolSize) {
// 输入值不能小于0或者大于线程池的容量
if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
// delta = 传入核心线程数和现存的核心线程数的差值
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
// 如果当前线程池工作线程的总量大于传入核心线程数,则中断所有的工作线程
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// 传入核心线程数和现存的核心线程数的差值大于0,也就是核心线程扩容
// 计算传入核心线程数和现存的核心线程数的差值和任务队列中任务个数的最小值,
//并且添加这个最小值个数的工作线程池
// 任务队列为空的情况下,k === 0,此时第一个条件 k--> 0就不满足,不会进入循环
//那么这delta个需要创建的工作线程应该是在提交新任务的时候懒创建
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
// 如果任务队列为空,则跳出循环
if (workQueue.isEmpty())
break;
}
}
}
分析:这里else if (delta > 0)后面的代码块中有一段描述,翻译一下:
我们并不知道真正情况下"需要"多少新的工作线程。作为一种启发式处理方式,
预先启动足够多的新的工作线程(直到数量为核心线程池大小)来处理队列中当前的任务,
但如果在这样做时队列变为空,则停止创建新的工作线程。
学习来源:https://www.cnblogs.com/throwable/p/13574306.html