- 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/
最近,我们将专用 SQL 池部署到生产中的 Synapse 工作区。在开发中,我们可以访问无服务器 SQL 池和专用 SQL 池。但是,在生产中,我们可以访问无服务器 SQL 池,但无法访问专用 SQ
假设您从一个项目公开 WCF 服务,并使用“添加服务引用”(在本例中为 Framework 3.5 WPF 应用程序)在另一个项目中使用它。 当您重新实例化 ClientBase 派生代理时,Clie
我有一个函数,它使用 multiprocessing.Pool 并行处理一个数据集中的所有数据。 from multiprocessing import Pool ... def func():
我正在尝试使用进程对象在 python 中使用工作池。每个 worker (一个进程)进行一些初始化(花费大量时间),传递一系列作业(理想情况下使用 map()),并返回一些东西。除此之外,不需要任何
我是软件工程师,最近我构建了我的 Linux 机器,想探索更多系统管理员类型的任务。我已经探索并阅读了很多关于 ZFS 的内容,但我越来越困惑,因为每篇文章对它的描述都不一样。 Everything
我有 zfs 池: $ sudo zpool status lxd pool: lxd state: ONLINE scan: none requested config: NAME
我有一个基于 Actor 的项目,对于其中的一部分,我必须使用一些接收消息的 Actor ,然后一个 Actor 分别分配给每个请求,每个 Actor 负责执行其消息请求,所以我需要类似线程的东西我的
我已经使用 QEMU 模拟器成功地将 FreeBSD 安装到原始图像文件中。我已经使用 ZFS 文件系统 (ZFS POOL) 格式化了图像文件。 使用下面的命令我已经成功地挂载了准备好由 zpool
我正在使用 multiprocessor.Pool并行处理一些文件。该代码等待接收文件,然后使用 Pool.apply_async 将该文件发送给工作人员。 ,然后处理文件。 这段代码应该一直在运行,
我正在使用带有光滑的 Bonecp 数据源。并发现池包含关闭的连接所以我总是遇到这个异常 java.sql.SQLException: Connection is closed! at com
我有apartment gem的 Multi-Tenancy Rails应用程序,我可以使用apartment-sidekiq在每个工作程序中成功切换数据库租户。但是,sidekiq worker 正
ZFS 池可能由数据集(文件系统、快照等)或卷组成。 ZFS 卷就像 block 设备,但我不明白池和文件系统之间的区别。当我通过 zpool create pool1 sda sdb sdc 创建
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我在tomcat中有一个jdbc池,用于建立数据库连接。我在使用后没有显式关闭连接对象。我的“maxActive”参数设置为100。应用程序运行了一段时间,但随后失败进行数据库查询。它会等待无限时间来
阅读 PostgreSQL 文档 here我读了以下内容: As well, connections requested for users other than the default config
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我正在读取一个大的 URL 文件并向服务发出请求。该请求由返回 ListenableFuture 的客户端执行。现在我想保留一个 ListenableFuture 池,例如最多同时执行 N 个 Fut
我想使用队列来保存结果,因为我希望消费者(串行而不是并行)在工作人员产生结果时处理工作人员的结果。 现在,我想知道为什么以下程序挂起。 import multiprocessing as mp imp
我正在开发一个单页应用程序,目前正在构建一个 JQuery、ajax 函数,以便我的所有调用都能通过。 对于一个典型的页面,我可能有 3 个 ajax 调用。我的想法是,如果用户互联网出去将这些 aj
我有一个单位类及其一些子类(弓箭手、剑客等)。我怎样才能创建一个回收所有单元类型子类的池? 最佳答案 这是不可能的,因为池只能包含一种特定类型的对象。否则你可能会遇到这样的情况: Pool unitP
我是一名优秀的程序员,十分优秀!