核心池大小与ThreadPoolExecutor中的最大池大小

当我们使用ThreadPoolExecutor进行交谈时,核心池大小和最大池大小究竟有什么区别? 可以用一个例子来解释吗?

从这个博客文章 :

以这个例子。 启动线程池大小为1,核心池大小为5,最大池大小为10,队列为100。

随着请求的进入,线程将被创build到5,然后任务将被添加到队列中,直到达到100.当队列已满时,新线程将被创build到maxPoolSize 。 一旦所有的线程都在使用中,并且队列已满,任务将被拒绝。 随着队列的减less,活动线程数量也随之减less。

从文档 :

当在方法execute(java.lang.Runnable)中提交新任务并且less于corePoolSize线程正在运行时,即使其他工作线程处于空闲状态,也会创build一个新线程来处理该请求。 如果有多于corePoolSize但小于maximumPoolSize线程正在运行,则只有在队列已满时才会创build一个新线程。

此外:

通过设置corePoolSize和maximumPoolSize相同,您可以创build一个固定大小的线程池。 通过将maximumPoolSize设置为基本上无界的值(例如Integer.MAX_VALUE),可以让池容纳任意数量的并发任务。 最典型的是,核心和最大池大小只在构build时设置,但也可以使用setCorePoolSize(int)和setMaximumPoolSize(int)dynamic更改。

如果您决定手动创buildThreadPoolExecutor而不是使用Executors工厂类,则需要使用其构造函数之一来创build和configuration一个。 这个类最广泛的构造函数是:

 public ThreadPoolExecutor( int corePoolSize, int maxPoolSize, long keepAlive, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler ); 

正如你所看到的,你可以configuration:

  • 核心池大小(线程池将尝试坚持的大小)。
  • 最大池大小。
  • 保持活动时间,这是一个空闲线程有资格被拆除的时间。
  • 工作队列保存等待执行的任务。
  • 拒绝任务提交时应用的策略。

限制排队任务的数量

限制正在执行的并发任务的数量,根据可预测性和稳定性,为您的应用程序及其执行环境提供巨大的好处:无限制的线程创build将最终耗尽运行时资源,您的应用程序可能会因此受到影响,严重的性能问题甚至可能导致应用程序不稳定。

这只是解决问题的一部分的一个解决scheme:您正在限制正在执行的任务数量,但不限制可以提交和排队等待以后执行的作业数量。 应用程序将在稍后遇到资源短缺,但如果提交率一直超出执行率,则最终会遇到这种情况。

解决这个问题的方法是:为执行者提供一个阻塞队列来保存等待的任务。 在队列填满的情况下,提交的任务将被“拒绝”。 当任务提交被拒绝时, RejectedExecutionHandler被调用,这就是为什么被拒绝的动词被引用在前一个项目中的原因。 您可以实施自己的拒绝政策,或使用框架提供的内置政策之一。

默认的拒绝策略是执行程序抛出一个RejectedExecutionException 。 但是,其他内置策略可让您:

  • 默默地放弃工作。
  • 丢弃最古老的工作,并尝试重新提交最后一个。
  • 在调用者的线程上执行被拒绝的任务。

您可以在javadoc中find术语corepoolsize和maxpoolsize的定义。 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

上面的链接有你的问题的答案。 但是,只是为了说清楚。 应用程序将继续创build线程,直到达到corePoolSize。 我认为这里的想法是这些线程应该足以处理任务的stream入。 如果在创buildcorePoolSize线程后出现新任务,任务将排队。 一旦队列满了,执行程序将开始创build新的线程。 这是一种平衡。 其实质意味着任务的stream入不仅仅是处理能力。 所以,Executor会再次开始创build新线程,直到达到最大线程数。 同样,当且仅当队列已满时才会创build新线程。