Java更改工作线程数量

时间:2015-07-21 11:09:51

标签: java multithreading threadpool

我正在使用ExecutorService来创建一个固定的线程池并启动几个工作线程来监听发生的事情,然后完成他们的工作。 但有时我想增加或减少同时运行的线程数量,以便微调应用程序的性能(无需重新启动应用程序或终止任何当前运行的线程)。 我应该创建自己的线程池,还是有办法让池大小改变,以便在必要时处理工作人员的开始/停止。

3 个答案:

答案 0 :(得分:3)

ThreadPoolExecutor可以让你这样做。请参阅setCorePoolSizesetMaximumPoolSize

答案 1 :(得分:3)

  

但有时候我想增加或减少金额   同时运行的线程,以便微调   应用程序的性能(无需重新启动应用程序或杀死任何应用程序   目前正在运行线程)。

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

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

corePoolSize和maximumPoolSize:

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

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

  

但是,程序员被要求使用更方便的Executors   工厂方法Executors.newCachedThreadPool()(无界线程   池,自动线程回收),   Executors.newFixedThreadPool(int)(固定大小的线程池)和   Executors.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);
    }
}

答案 2 :(得分:1)

ThreadPoolExecutor动态增加和缩小线程数。确保正确设置池大小。 CorePoolSize定义生成的最大线程数。当BlockingQueue定义为有限大小时,MaxPoolSize可以播放。当您具有有限的队列大小时,会为每个提交的新任务生成新线程,直到达到核心池大小。如果队列中的请求数增加超过队列的有限大小,则会生成新线程,直到它们到达MaxPoolSize。