Java改变工作线程的数量



我使用ExecutorService创建一个固定的线程池,并启动几个工作线程,这些线程侦听发生的事情,然后执行它们的工作。然而,有时我想增加或减少同时运行的线程数量,以便微调应用程序的性能(不重新启动应用程序或杀死任何当前正在运行的线程)。我是否应该创建自己的线程池,或者是否有一种方法可以改变线程池的大小,以便在必要时处理工作线程的启动/停止。

然而,有时我想增加或减少的数量同时运行的线程,以便微调应用程序的性能(不重启应用程序或杀死任何)

如果你的意思是使用一些工具或其他东西动态地改变,那么我不确定,但你可以放一些代码逻辑来控制。

您可以使用java.util.concurrent.ThreadPoolExecutor, CorePoolSizeMaxPoolSize属性来控制线程池。

corePoolSize and maximumPoolSize:

    ThreadPoolExecutor将根据corePoolSize(参见getCorePoolSize())和maximumPoolSize(参见getMaximumPoolSize())设置的界限自动调整池大小(参见getPoolSize())。
  • 当在execute(java.lang.Runnable)方法中提交一个新任务,并且运行的线程少于corePoolSize时,即使其他工作线程空闲,也会创建一个新线程来处理该请求。
  • 如果运行的线程数大于corePoolSize但小于maximumPoolSize,则只有当队列已满时才会创建新线程。

然而,在你决定之前,我建议你阅读下面摘自ThreadPoolExecutor的Java文档。

然而,程序员被敦促使用更方便的executor Executors.newCachedThreadPool()(无界线程,带有自动线程回收),newfixedthreadpool (int)(固定大小的线程池)newsinglethreadexecutor()(单个后台线程为最常见的使用场景预配置设置。


代码示例:
请参考下面的代码示例。您可以通过阅读代码和浏览Java文档来理解大多数内容。然而,有些可能不太明显的事实是

  • 我们使用ArrayBlockingQueue来获得一个容量为20的有界队列(您可以根据您的需求决定队列容量)。因此,一旦队列中等待的任务超过20个,就会创建新线程,但maxPoolSize的最大值为
  • 基于负载,我们正在增加核心池线程的数量,这意味着更多的线程将处理您的任务,因此任务排队的机会更少。但是你也可以使用maxPoolSize。

你可以阅读ThreadPoolExecutor的"排队"部分,并根据你的需要决定使用其他队列。

ThreadPoolExecutor.setCorePoolSize (int)
设置核心线程数。这将覆盖构造函数中设置的任何值。如果新值小于当前值,多余的现有线程将在它们下次空闲时被终止。如果更大,如果需要,将启动新的线程来执行任何排队的任务

    //Read Java docs for details about construcutor...
    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10, 100, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20));
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //Do your task...
        }
    };
    executeTasks(poolExecutor, runnable, false, false); //Compute last 2 parameters as you need and pass on required values.
public static void executeTasks(ThreadPoolExecutor poolExecutor, Runnable runnable, boolean isUnderLoad, boolean isOverLoad){
    if(isOverLoad && isUnderLoad){
        //Handle this situation, this should not be allowed, probably a coding bug can result this...
    }
    poolExecutor.submit(runnable);
    if(isUnderLoad){
        poolExecutor.setCorePoolSize(5);
    }
    if(isOverLoad){
        poolExecutor.setCorePoolSize(20);
    }
}

ThreadPoolExecutor允许您这样做。参见setCorePoolSize和setMaximumPoolSize

ThreadPoolExecutor动态地增加和减少线程数。确保正确设置池大小。CorePoolSize定义了生成的最大线程数。当BlockingQueue定义为有限大小时,MaxPoolSize将发挥作用。当队列大小有限时,每个提交的新任务都会生成新线程,直到达到核心池大小。如果队列中的请求数量增加超过队列的有限大小,则产生新线程,直到它们达到MaxPoolSize。

最新更新