- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我作为初学者正在学习java中的线程和并发包,并且我已经阅读了有关 ThreadPoolExecutor 的文档以了解 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());
}
});
}
执行上述程序时,我可以看到队列大小达到 b/w 12000-20000,如果是这种情况,那么 getPoolSize()
必须打印大于 corePoolSize 的值,因为设置了 maxPoolSize到 10 但每次它只会打印 3(这是 corePoolSize) 为什么会发生这种情况?正如我们预期的那样,它可以扩展到 maxPoolSize。
最佳答案
Executors.newFixedThreadPool
返回 ExecutorService
;一个不公开(并且可能有充分理由)方法的接口(interface),例如 setMaximumPoolSize
和 setCorePoolSize
.
如果您创建 Executors.newFixedThreadPool
类型的池,此池应在应用程序的生命周期内保持固定。如果您想要一个可以相应调整其大小的池,您应该使用 Executors.newCachedThreadPool()
而是。
From my understanding, Executors.newFixedThreadPool(3) creates a poolwith corePoolSize-3 (...)
看newFixedThreadPool
的实现可以看出:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
和
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
所以当你通过 3
到Executors.newFixedThreadPool
构造函数,你设置 both corePoolSize
和 maximumPoolSize
至3
.
(...) and as we keep executing tasks via pool, threads will be created until3 and then when the underlying queue size reaches 100 and new tasksare still submitted then that's where maxPoolSize comes into pictureand threads are scaled to reach maxPoolSize from corePoolSize now.
其实这个不是很准确,后面会详细解释。现在阅读 Executors.newFixedThreadPool
的 Java 文档它指出:
Creates a thread pool that reuses a fixed number of threads operatingoff a shared unbounded queue. At any point, at most nThreads threadswill be active processing tasks. If additional tasks are submittedwhen all threads are active, they will wait in the queue until athread is available.
因此,池没有缩放(除非您明确这样做)。
When the above program is executed,i could see the queue size reachingb/w 12000-20000, if this the case then getPoolSize() must print thevalue greater than corePoolSize as maxPoolSize is set to 10 buteverytime it would only print 3(which is corePoolSize) why does thishappen ? as we expect it to scale upto maxPoolSize.
不,这不准确,如果您打印 pool.getMaximumPoolSize()
它将返回 10
不出所料,调用pool.setMaximumPoolSize(10);
不会改变 corePoolSize 的大小。但是,如果您这样做 pool.setCorePoolSize(10);
您将增加池以能够处理 10
同时线程。
this.maximumPoolSize
只是定义了池应该同时处理多少线程的上限,它不会改变池的当前大小。
为什么池不动态增加其大小?
深入了解newFixedThreadPool
实现,可以看到Pool初始化了一个任务队列new LinkedBlockingQueue<Runnable>()
大小等于 Integer.MAX_VALUE
.看方法execute
可以在评论中阅读以下内容:
/*
* 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.
*/
如果仔细阅读第 2 点和第 3 点,可以推断只有当无法将任务添加到队列时,池才会创建比 corePoolSize 指定的线程更多的线程。自从 Executors.newFixedThreadPool
使用带有 Integer.MAX_VALUE
的队列您无法看到池动态分配更多资源,除非明确设置 corePoolSize
与 pool.setCorePoolSize
.
所有这些都是不需要关心的实现细节。因此,为什么 Executors
接口(interface)不暴露方法如 setMaximumPoolSize
.
来自 ThreadPoolExecutor可以阅读的文档:
核心和最大池大小
A ThreadPoolExecutor will automatically adjust the pool size (seegetPoolSize()) according to the bounds set by corePoolSize (seegetCorePoolSize()) and maximumPoolSize (see getMaximumPoolSize()).When a new task is submitted in method execute(java.lang.Runnable),and fewer than corePoolSize threads are running, a new thread iscreated to handle the request, even if other worker threads are idle.If there are more than corePoolSize but less than maximumPoolSizethreads running, a new thread will be created only if the queue isfull. By setting corePoolSize and maximumPoolSize the same, you createa fixed-size thread pool. By setting maximumPoolSize to an essentiallyunbounded value such as Integer.MAX_VALUE, you allow the pool toaccommodate an arbitrary number of concurrent tasks. Most typically,core and maximum pool sizes are set only upon construction, but theymay also be changed dynamically using setCorePoolSize(int) andsetMaximumPoolSize(int).
这基本上证实了为什么池没有动态更新其大小。
关于java - 使用 ThreadPoolExecutor 缩放 maxPoolSize;为什么池不会动态增加其大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65512477/
我已经设置了自定义线程配置文件,我可以看到从以下配置创建了 20 个线程。 但我从来没有看到线程数增加到 20 以上,但最大池大小配置为 50。什么时候使用最大池大小? 我们尝试对 50 个具有并发
我使用 HikariConfig 作为 spring 服务器上 postgres 数据库的数据源。我应该设置 maxPoolSize 吗? (默认值为 -1)我可以使用多少池大小?是否与硬件有任何依赖
在连接到数据库时,我使用连接池和 Firebird 数据库。我使用 FirebirdSql.Data.FirebirdClient 版本 2.6.5.0。我有以下连接字符串: 我有以下使用数据库连接
我将 MaxPoolSize 值增加到 3000。这是否意味着允许使用此实例的并发连接数为 3000,或者它也计算通过其他对象实例的任何其他连接数? var connectionString = "m
我遇到了可怕的错误: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool
我作为初学者正在学习java中的线程和并发包,并且我已经阅读了有关 ThreadPoolExecutor 的文档以了解 getPoolSize() 和 getCorePoolSize() 之间的区别,
这个问题在这里已经有了答案: How to get the ThreadPoolExecutor to increase threads to max before queueing? (10 个回答
我们有一个托管在 RDS 中的 MySQl 数据库。创建 MySQL 连接时,似乎未应用最大池大小。我们有一个看起来像这样的连接字符串 Server=myServer;Port=3306;Databa
我的应用程序中有 8 个 Verticle。每个 Verticle 都在一个单独的线程上。每个 Verticle 都有一个 WebClient(Vert.x HTTP 客户端)我将 MaxPoolSi
我已将 Tomcat 配置为使用 ComboPooledDataSource,方法是在我的 context.xml 中添加以下内容。 我想将数据库连接数限制为 20,如 maxPoolSize 中所
我试图找出我们服务中一些随机、间歇性“卡住”的根本原因,在排除了几个问题后,我们为我们的应用程序打开了 c3p0 调试级别的日志记录,我们认为这似乎是一个 c3p0 配置问题。我们使用“Oracle
我的申请是 Piwik Server从放置在数百个网站上的跟踪代码接收传入的跟踪数据。当这些跟踪请求进入时,大部分工作负载是每秒向数据库写入数百次。我使用的是带有 JDBC 和 Hibernate 的
当使用 golang 连接到 mongodb 实例时,我们可以指定 maxPoolSize 的值通过 connection string或使用 ClientOptions.SetMaxPoolSize
所以我有两个 bash 脚本。一个使用“scala”命令调用字节码,另一个使用“java”命令调用相同的代码。我的问题如下,当我使用 scala 时,我可以看到我可以获得大约 80 个线程(我创建并显
我必须向网站的所有用户发送大量电子邮件。我想为每封发送的电子邮件使用一个线程池。目前我已将值设置为: 两者之间有什么区别,是否会扩展。目前我有大约。 10000 个用户。 最佳答案 以下是 Sun
我在vertx java中创建了一个java后端服务。我使用 httpClient(io.vertx.core.http.HttpClient) 并启用连接池来连接到外部服务。我排除吞吐量为 50。对
我有一个 SwingWorker 可以获取 URL 列表(可能有数百个)。在 doInBackground() 方法中,它循环遍历这些 URL,每次创建一个 CloseableHttpClient,由
executor.setCorePoolSize(5); executor.setMaxPoolSize(5); 我在 Spring 中有一个 UI 应用程序和后端。一种方法需要 15 秒才能执行。我
如何在 mongodb-php 驱动程序版本 1.2.0 中使用 maxPoolSize。 新的 mongodb php 驱动程序是否使用连接池,如果是那么如何更改它? 最佳答案 你可以使用 Mong
我是一名优秀的程序员,十分优秀!