Java 使用ThreadPoolExecutor缩放maxPoolSize;为什么池不动态增加其大小?
作为初学者,我正在学习java中的线程和并发包,我已经阅读了关于ThreadPoolExecutor的文档,以了解Java 使用ThreadPoolExecutor缩放maxPoolSize;为什么池不动态增加其大小?,java,multithreading,performance,parallel-processing,threadpool,Java,Multithreading,Performance,Parallel Processing,Threadpool,作为初学者,我正在学习java中的线程和并发包,我已经阅读了关于ThreadPoolExecutor的文档,以了解getPoolSize()、getCorePoolSize()、getMaxPoolSize()之间的区别,并尝试在代码中实现相同的功能 背景位 据我所知,Executors.newFixedThreadPool(3)创建了一个具有 corePoolSize=3,当我们继续通过池执行任务时,将创建线程,直到3,然后当基础队列大小达到100并且仍然提交新任务时,这就是maxPoolSi
getPoolSize()
、getCorePoolSize()
、getMaxPoolSize()
之间的区别,并尝试在代码中实现相同的功能
背景位
据我所知,Executors.newFixedThreadPool(3)
创建了一个具有
corePoolSize=3,当我们继续通过池执行任务时,将创建线程,直到3,然后当基础队列大小达到100并且仍然提交新任务时,这就是maxPoolSize出现的地方,现在线程从corePoolSize缩放到maxPoolSize
public class Test {
static ThreadPoolExecutor pool=(ThreadPoolExecutor)Executors.newFixedThreadPool(3);
public static void main(String k[]) throws InterruptedException{
BlockingQueue<Runnable> queue=pool.getQueue();
pool.execute(()->{
for(int b=0;b<10;b++)
System.out.println("Hello "+b);
});
pool.execute(()->{
for(int b=0;b<10;b++)
System.out.println("Hello "+b);
});
pool.setMaximumPoolSize(10); //Setting maxPoolSize
for(int j=0;j<20000;j++)
pool.execute(()->{
for(int b=0;b<100;b++){
System.out.println("Hello "+b);
System.out.println("Queue size "+queue.size()+" "+"and pool size "+pool.getPoolSize());
}
});
}
公共类测试{
静态ThreadPoolExecutor池=(ThreadPoolExecutor)Executors.newFixedThreadPool(3);
公共静态void main(字符串k[])引发InterruptedException{
BlockingQueue=pool.getQueue();
pool.execute(()->{
对于(int b=0;b{
for(int b=0;bExecutors.newFixedThreadPool
返回一个ExecutorService
;一个接口,该接口不公开(可能是很好的理由)方法,如setMaximumPoolSize
和setCorePoolSize
如果创建类型为Executors.newFixedThreadPool
的池,则此池应在应用程序的生命周期内保持不变。如果希望池能够相应地调整其大小,则应使用Executors.newCachedThreadPool()
据我所知,Executors.newFixedThreadPool(3)创建了一个池
使用corePoolSize-3(…)
查看newFixedThreadPool
的实现可以看到:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
如果仔细阅读第2点和第3点,可以推断,只有当任务无法添加到队列中时,池才会创建比corePoolSize指定的线程更多的线程。而且,由于执行者。newFixedThreadPool
使用带有整数的队列。MAX_VALUE
您无法看到池动态分配更多线程资源,除非使用pool.setCorePoolSize
显式设置corePoolSize
所有这些都是不必关心的实现细节。因此,为什么执行器
接口不公开方法,例如setMaximumPoolSize
从文档中可以看到:
核心池和最大池大小
ThreadPoolExecutor将自动调整池大小(请参阅
getPoolSize())根据corePoolSize设置的边界(请参阅
getCorePoolSize()和maximumPoolSize(请参阅getMaximumPoolSize())。
在方法execute(java.lang.Runnable)中提交新任务时,
如果运行的线程少于corePoolSize,则会创建一个新线程
创建以处理请求,即使其他工作线程处于空闲状态。
如果超过corePoolSize但小于maximumPoolSize
线程运行时,仅当队列为
完整。通过将corePoolSize和maximumPoolSize设置为相同,您可以创建
固定大小的线程池。通过将maximumPoolSize设置为
无界值,如Integer.MAX_值,则允许池
可容纳任意数量的并发任务。通常,
核心池和最大池大小仅在施工时设置,但
也可以使用setCorePoolSize(int)和
setMaximumPoolSize(int)
这基本上证实了池没有动态更新其大小的原因
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
/*
* 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.
*/