From e8c0ef8305cedc43e9cb5f08ba2d9aa9d991ff1d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 2 Sep 2013 21:18:41 +0200 Subject: [PATCH] ThreadPoolTaskScheduler allows for setPoolSize changes at runtime Also exposing "getPoolSize()" and "getActiveCount()" from ThreadPoolTaskScheduler now, analogous to ThreadPoolTaskExecutor. Issue: SPR-10883 --- .../concurrent/ThreadPoolTaskExecutor.java | 18 ++++--- .../concurrent/ThreadPoolTaskScheduler.java | 49 ++++++++++++++++++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java index 6674768af79..b73871ae2da 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -154,9 +154,7 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport impleme * Specify whether to allow core threads to time out. This enables dynamic * growing and shrinking even in combination with a non-zero queue (since * the max pool size will only grow once the queue is full). - *

Default is "false". Note that this feature is only available on Java 6 - * or above. On Java 5, consider switching to the backport-concurrent - * version of ThreadPoolTaskExecutor which also supports this feature. + *

Default is "false". * @see java.util.concurrent.ThreadPoolExecutor#allowCoreThreadTimeOut(boolean) */ public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) { @@ -225,7 +223,11 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport impleme * @see java.util.concurrent.ThreadPoolExecutor#getPoolSize() */ public int getPoolSize() { - return getThreadPoolExecutor().getPoolSize(); + if (this.threadPoolExecutor == null) { + // Not initialized yet: assume core pool size. + return this.corePoolSize; + } + return this.threadPoolExecutor.getPoolSize(); } /** @@ -233,7 +235,11 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport impleme * @see java.util.concurrent.ThreadPoolExecutor#getActiveCount() */ public int getActiveCount() { - return getThreadPoolExecutor().getActiveCount(); + if (this.threadPoolExecutor == null) { + // Not initialized yet: assume no active threads. + return 0; + } + return this.threadPoolExecutor.getActiveCount(); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index 01c05d6bc4c..6ba108732bb 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,14 +62,18 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport /** * Set the ScheduledExecutorService's pool size. * Default is 1. + *

This setting can be modified at runtime, for example through JMX. */ public void setPoolSize(int poolSize) { Assert.isTrue(poolSize > 0, "'poolSize' must be 1 or higher"); this.poolSize = poolSize; + if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) { + ((ScheduledThreadPoolExecutor) this.scheduledExecutor).setCorePoolSize(poolSize); + } } /** - * Provide an {@link ErrorHandler} strategy. + * Set a custom {@link ErrorHandler} strategy. */ public void setErrorHandler(ErrorHandler errorHandler) { Assert.notNull(errorHandler, "'errorHandler' must not be null"); @@ -111,6 +115,47 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport return this.scheduledExecutor; } + /** + * Return the underlying ScheduledThreadPoolExecutor, if available. + * @return the underlying ScheduledExecutorService (never {@code null}) + * @throws IllegalStateException if the ThreadPoolTaskScheduler hasn't been initialized yet + * or if the underlying ScheduledExecutorService isn't a ScheduledThreadPoolExecutor + * @see #getScheduledExecutor() + */ + public ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor() throws IllegalStateException { + Assert.state(this.scheduledExecutor instanceof ScheduledThreadPoolExecutor, + "No ScheduledThreadPoolExecutor available"); + return (ScheduledThreadPoolExecutor) this.scheduledExecutor; + } + + /** + * Return the current pool size. + *

Requires an underlying {@link ScheduledThreadPoolExecutor}. + * @see #getScheduledThreadPoolExecutor() + * @see java.util.concurrent.ScheduledThreadPoolExecutor#getPoolSize() + */ + public int getPoolSize() { + if (this.scheduledExecutor == null) { + // Not initialized yet: assume initial pool size. + return this.poolSize; + } + return getScheduledThreadPoolExecutor().getPoolSize(); + } + + /** + * Return the number of currently active threads. + *

Requires an underlying {@link ScheduledThreadPoolExecutor}. + * @see #getScheduledThreadPoolExecutor() + * @see java.util.concurrent.ScheduledThreadPoolExecutor#getActiveCount() + */ + public int getActiveCount() { + if (this.scheduledExecutor == null) { + // Not initialized yet: assume no active threads. + return 0; + } + return getScheduledThreadPoolExecutor().getActiveCount(); + } + // SchedulingTaskExecutor implementation