14 changed files with 1 additions and 1704 deletions
@ -1,138 +0,0 @@
@@ -1,138 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.backportconcurrent; |
||||
|
||||
import java.util.concurrent.Callable; |
||||
import java.util.concurrent.Future; |
||||
import java.util.concurrent.FutureTask; |
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executors; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionException; |
||||
|
||||
import org.springframework.core.task.TaskRejectedException; |
||||
import org.springframework.scheduling.SchedulingTaskExecutor; |
||||
|
||||
/** |
||||
* Adapter that takes a JSR-166 backport |
||||
* {@code edu.emory.mathcs.backport.java.util.concurrent.Executor} and |
||||
* exposes a Spring {@link org.springframework.core.task.TaskExecutor} for it. |
||||
* |
||||
* <p><b>NOTE:</b> This class implements Spring's |
||||
* {@link org.springframework.core.task.TaskExecutor} interface (and hence implicitly |
||||
* the standard Java 5 {@link java.util.concurrent.Executor} interface) as well as |
||||
* the JSR-166 {@link edu.emory.mathcs.backport.java.util.concurrent.Executor} |
||||
* interface, with the former being the primary interface, the other just |
||||
* serving as secondary convenience. For this reason, the exception handling |
||||
* follows the TaskExecutor contract rather than the backport Executor contract, in |
||||
* particular regarding the {@link org.springframework.core.task.TaskRejectedException}. |
||||
* |
||||
* <p>Note that there is a pre-built {@link ThreadPoolTaskExecutor} that allows for |
||||
* defining a JSR-166 backport |
||||
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor} in bean |
||||
* style, exposing it as a Spring {@link org.springframework.core.task.TaskExecutor} |
||||
* directly. This is a convenient alternative to a raw ThreadPoolExecutor |
||||
* definition with a separate definition of the present adapter class. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 2.0.3 |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors |
||||
* @see ThreadPoolTaskExecutor |
||||
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support |
||||
*/ |
||||
@Deprecated |
||||
public class ConcurrentTaskExecutor implements SchedulingTaskExecutor, Executor { |
||||
|
||||
private Executor concurrentExecutor; |
||||
|
||||
|
||||
/** |
||||
* Create a new ConcurrentTaskExecutor, |
||||
* using a single thread executor as default. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors#newSingleThreadExecutor() |
||||
*/ |
||||
public ConcurrentTaskExecutor() { |
||||
setConcurrentExecutor(null); |
||||
} |
||||
|
||||
/** |
||||
* Create a new ConcurrentTaskExecutor, |
||||
* using the given JSR-166 backport concurrent executor. |
||||
* @param concurrentExecutor the JSR-166 backport concurrent executor to delegate to |
||||
*/ |
||||
public ConcurrentTaskExecutor(Executor concurrentExecutor) { |
||||
setConcurrentExecutor(concurrentExecutor); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Specify the JSR-166 backport concurrent executor to delegate to. |
||||
*/ |
||||
public final void setConcurrentExecutor(Executor concurrentExecutor) { |
||||
this.concurrentExecutor = |
||||
(concurrentExecutor != null ? concurrentExecutor : Executors.newSingleThreadExecutor()); |
||||
} |
||||
|
||||
/** |
||||
* Return the JSR-166 backport concurrent executor that this adapter |
||||
* delegates to. |
||||
*/ |
||||
public final Executor getConcurrentExecutor() { |
||||
return this.concurrentExecutor; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Delegates to the specified JSR-166 backport concurrent executor. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor#execute(Runnable) |
||||
*/ |
||||
public void execute(Runnable task) { |
||||
try { |
||||
this.concurrentExecutor.execute(task); |
||||
} |
||||
catch (RejectedExecutionException ex) { |
||||
throw new TaskRejectedException( |
||||
"Executor [" + this.concurrentExecutor + "] did not accept task: " + task, ex); |
||||
} |
||||
} |
||||
|
||||
public void execute(Runnable task, long startTimeout) { |
||||
execute(task); |
||||
} |
||||
|
||||
public Future<?> submit(Runnable task) { |
||||
FutureTask<Object> future = new FutureTask<Object>(task, null); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
public <T> Future<T> submit(Callable<T> task) { |
||||
FutureTask<T> future = new FutureTask<T>(task); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
/** |
||||
* This task executor prefers short-lived work units. |
||||
*/ |
||||
public boolean prefersShortLivedTasks() { |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
@ -1,61 +0,0 @@
@@ -1,61 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.backportconcurrent; |
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory; |
||||
|
||||
import org.springframework.util.CustomizableThreadCreator; |
||||
|
||||
/** |
||||
* Implementation of the JSR-166 backport |
||||
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory} interface, |
||||
* allowing for customizing the created threads (name, priority, etc). |
||||
* |
||||
* <p>See the base class {@link org.springframework.util.CustomizableThreadCreator} |
||||
* for details on the available configuration options. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 2.0.3 |
||||
* @see #setThreadNamePrefix |
||||
* @see #setThreadPriority |
||||
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support |
||||
*/ |
||||
@SuppressWarnings("serial") |
||||
@Deprecated |
||||
public class CustomizableThreadFactory extends CustomizableThreadCreator implements ThreadFactory { |
||||
|
||||
/** |
||||
* Create a new CustomizableThreadFactory with default thread name prefix. |
||||
*/ |
||||
public CustomizableThreadFactory() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Create a new CustomizableThreadFactory with the given thread name prefix. |
||||
* @param threadNamePrefix the prefix to use for the names of newly created threads |
||||
*/ |
||||
public CustomizableThreadFactory(String threadNamePrefix) { |
||||
super(threadNamePrefix); |
||||
} |
||||
|
||||
|
||||
public Thread newThread(Runnable runnable) { |
||||
return createThread(runnable); |
||||
} |
||||
|
||||
} |
||||
@ -1,385 +0,0 @@
@@ -1,385 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.backportconcurrent; |
||||
|
||||
import java.util.concurrent.Callable; |
||||
import java.util.concurrent.Future; |
||||
import java.util.concurrent.FutureTask; |
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.Executor; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionException; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionHandler; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor; |
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.beans.factory.BeanNameAware; |
||||
import org.springframework.beans.factory.DisposableBean; |
||||
import org.springframework.beans.factory.InitializingBean; |
||||
import org.springframework.core.task.TaskRejectedException; |
||||
import org.springframework.scheduling.SchedulingTaskExecutor; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* JavaBean that allows for configuring a JSR-166 backport |
||||
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor} in bean |
||||
* style (through its "corePoolSize", "maxPoolSize", "keepAliveSeconds", "queueCapacity" |
||||
* properties), exposing it as a Spring {@link org.springframework.core.task.TaskExecutor}. |
||||
* This is an alternative to configuring a ThreadPoolExecutor instance directly using |
||||
* constructor injection, with a separate {@link ConcurrentTaskExecutor} adapter wrapping it. |
||||
* |
||||
* <p>For any custom needs, in particular for defining a |
||||
* {@link edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor}, |
||||
* it is recommended to use a straight definition of the Executor instance or a |
||||
* factory method definition that points to the JSR-166 backport |
||||
* {@link edu.emory.mathcs.backport.java.util.concurrent.Executors} class. |
||||
* To expose such a raw Executor as a Spring {@link org.springframework.core.task.TaskExecutor}, |
||||
* simply wrap it with a {@link ConcurrentTaskExecutor} adapter. |
||||
* |
||||
* <p><b>NOTE:</b> This class implements Spring's |
||||
* {@link org.springframework.core.task.TaskExecutor} interface (and hence implicitly |
||||
* the standard Java 5 {@link java.util.concurrent.Executor} interface) as well as |
||||
* the JSR-166 {@link edu.emory.mathcs.backport.java.util.concurrent.Executor} |
||||
* interface, with the former being the primary interface, the other just |
||||
* serving as secondary convenience. For this reason, the exception handling |
||||
* follows the TaskExecutor contract rather than the backport Executor contract, in |
||||
* particular regarding the {@link org.springframework.core.task.TaskRejectedException}. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 2.0.3 |
||||
* @see org.springframework.core.task.TaskExecutor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors |
||||
* @see ConcurrentTaskExecutor |
||||
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support |
||||
*/ |
||||
@Deprecated |
||||
@SuppressWarnings("serial") |
||||
public class ThreadPoolTaskExecutor extends CustomizableThreadFactory |
||||
implements SchedulingTaskExecutor, Executor, BeanNameAware, InitializingBean, DisposableBean { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private final Object poolSizeMonitor = new Object(); |
||||
|
||||
private int corePoolSize = 1; |
||||
|
||||
private int maxPoolSize = Integer.MAX_VALUE; |
||||
|
||||
private int keepAliveSeconds = 60; |
||||
|
||||
private boolean allowCoreThreadTimeOut = false; |
||||
|
||||
private int queueCapacity = Integer.MAX_VALUE; |
||||
|
||||
private ThreadFactory threadFactory = this; |
||||
|
||||
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); |
||||
|
||||
private boolean waitForTasksToCompleteOnShutdown = false; |
||||
|
||||
private boolean threadNamePrefixSet = false; |
||||
|
||||
private String beanName; |
||||
|
||||
private ThreadPoolExecutor threadPoolExecutor; |
||||
|
||||
|
||||
/** |
||||
* Set the ThreadPoolExecutor's core pool size. |
||||
* Default is 1. |
||||
* <p><b>This setting can be modified at runtime, for example through JMX.</b> |
||||
*/ |
||||
public void setCorePoolSize(int corePoolSize) { |
||||
synchronized (this.poolSizeMonitor) { |
||||
this.corePoolSize = corePoolSize; |
||||
if (this.threadPoolExecutor != null) { |
||||
this.threadPoolExecutor.setCorePoolSize(corePoolSize); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the ThreadPoolExecutor's core pool size. |
||||
*/ |
||||
public int getCorePoolSize() { |
||||
synchronized (this.poolSizeMonitor) { |
||||
return this.corePoolSize; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Set the ThreadPoolExecutor's maximum pool size. |
||||
* Default is {@code Integer.MAX_VALUE}. |
||||
* <p><b>This setting can be modified at runtime, for example through JMX.</b> |
||||
*/ |
||||
public void setMaxPoolSize(int maxPoolSize) { |
||||
synchronized (this.poolSizeMonitor) { |
||||
this.maxPoolSize = maxPoolSize; |
||||
if (this.threadPoolExecutor != null) { |
||||
this.threadPoolExecutor.setMaximumPoolSize(maxPoolSize); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the ThreadPoolExecutor's maximum pool size. |
||||
*/ |
||||
public int getMaxPoolSize() { |
||||
synchronized (this.poolSizeMonitor) { |
||||
return this.maxPoolSize; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Set the ThreadPoolExecutor's keep-alive seconds. |
||||
* Default is 60. |
||||
* <p><b>This setting can be modified at runtime, for example through JMX.</b> |
||||
*/ |
||||
public void setKeepAliveSeconds(int keepAliveSeconds) { |
||||
synchronized (this.poolSizeMonitor) { |
||||
this.keepAliveSeconds = keepAliveSeconds; |
||||
if (this.threadPoolExecutor != null) { |
||||
this.threadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the ThreadPoolExecutor's keep-alive seconds. |
||||
*/ |
||||
public int getKeepAliveSeconds() { |
||||
synchronized (this.poolSizeMonitor) { |
||||
return this.keepAliveSeconds; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 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). |
||||
* <p>Default is "false". Note that this feature is only available on |
||||
* backport-concurrent 3.0 or above (based on the code in Java 6). |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#allowCoreThreadTimeOut(boolean) |
||||
*/ |
||||
public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) { |
||||
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut; |
||||
} |
||||
|
||||
/** |
||||
* Set the capacity for the ThreadPoolExecutor's BlockingQueue. |
||||
* Default is {@code Integer.MAX_VALUE}. |
||||
* <p>Any positive value will lead to a LinkedBlockingQueue instance; |
||||
* any other value will lead to a SynchronousQueue instance. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue |
||||
*/ |
||||
public void setQueueCapacity(int queueCapacity) { |
||||
this.queueCapacity = queueCapacity; |
||||
} |
||||
|
||||
/** |
||||
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool. |
||||
* <p>Default is this executor itself (i.e. the factory that this executor |
||||
* inherits from). See {@link org.springframework.util.CustomizableThreadCreator}'s |
||||
* javadoc for available bean properties. |
||||
* @see #setThreadPriority |
||||
* @see #setDaemon |
||||
*/ |
||||
public void setThreadFactory(ThreadFactory threadFactory) { |
||||
this.threadFactory = (threadFactory != null ? threadFactory : this); |
||||
} |
||||
|
||||
/** |
||||
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor. |
||||
* Default is the ThreadPoolExecutor's default abort policy. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.AbortPolicy |
||||
*/ |
||||
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) { |
||||
this.rejectedExecutionHandler = |
||||
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy()); |
||||
} |
||||
|
||||
/** |
||||
* Set whether to wait for scheduled tasks to complete on shutdown. |
||||
* <p>Default is "false". Switch this to "true" if you prefer |
||||
* fully completed tasks at the expense of a longer shutdown phase. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdown() |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdownNow() |
||||
*/ |
||||
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) { |
||||
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown; |
||||
} |
||||
|
||||
@Override |
||||
public void setThreadNamePrefix(String threadNamePrefix) { |
||||
super.setThreadNamePrefix(threadNamePrefix); |
||||
this.threadNamePrefixSet = true; |
||||
} |
||||
|
||||
public void setBeanName(String name) { |
||||
this.beanName = name; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Calls {@code initialize()} after the container applied all property values. |
||||
* @see #initialize() |
||||
*/ |
||||
public void afterPropertiesSet() { |
||||
initialize(); |
||||
} |
||||
|
||||
/** |
||||
* Creates the BlockingQueue and the ThreadPoolExecutor. |
||||
* @see #createQueue |
||||
*/ |
||||
public void initialize() { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Initializing ThreadPoolExecutor" + (this.beanName != null ? " '" + this.beanName + "'" : "")); |
||||
} |
||||
if (!this.threadNamePrefixSet && this.beanName != null) { |
||||
setThreadNamePrefix(this.beanName + "-"); |
||||
} |
||||
BlockingQueue queue = createQueue(this.queueCapacity); |
||||
this.threadPoolExecutor = new ThreadPoolExecutor( |
||||
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS, |
||||
queue, this.threadFactory, this.rejectedExecutionHandler); |
||||
if (this.allowCoreThreadTimeOut) { |
||||
this.threadPoolExecutor.allowCoreThreadTimeOut(true); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create the BlockingQueue to use for the ThreadPoolExecutor. |
||||
* <p>A LinkedBlockingQueue instance will be created for a positive |
||||
* capacity value; a SynchronousQueue else. |
||||
* @param queueCapacity the specified queue capacity |
||||
* @return the BlockingQueue instance |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue |
||||
*/ |
||||
protected BlockingQueue createQueue(int queueCapacity) { |
||||
if (queueCapacity > 0) { |
||||
return new LinkedBlockingQueue(queueCapacity); |
||||
} |
||||
else { |
||||
return new SynchronousQueue(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the underlying ThreadPoolExecutor for native access. |
||||
* @return the underlying ThreadPoolExecutor (never {@code null}) |
||||
* @throws IllegalStateException if the ThreadPoolTaskExecutor hasn't been initialized yet |
||||
*/ |
||||
public ThreadPoolExecutor getThreadPoolExecutor() throws IllegalStateException { |
||||
Assert.state(this.threadPoolExecutor != null, "ThreadPoolTaskExecutor not initialized"); |
||||
return this.threadPoolExecutor; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Implementation of both the JSR-166 backport Executor interface and the Spring |
||||
* TaskExecutor interface, delegating to the ThreadPoolExecutor instance. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor#execute(Runnable) |
||||
* @see org.springframework.core.task.TaskExecutor#execute(Runnable) |
||||
*/ |
||||
public void execute(Runnable task) { |
||||
Executor executor = getThreadPoolExecutor(); |
||||
try { |
||||
executor.execute(task); |
||||
} |
||||
catch (RejectedExecutionException ex) { |
||||
throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); |
||||
} |
||||
} |
||||
|
||||
public void execute(Runnable task, long startTimeout) { |
||||
execute(task); |
||||
} |
||||
|
||||
public Future<?> submit(Runnable task) { |
||||
FutureTask<Object> future = new FutureTask<Object>(task, null); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
public <T> Future<T> submit(Callable<T> task) { |
||||
FutureTask<T> future = new FutureTask<T>(task); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
/** |
||||
* This task executor prefers short-lived work units. |
||||
*/ |
||||
public boolean prefersShortLivedTasks() { |
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Return the current pool size. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#getPoolSize() |
||||
*/ |
||||
public int getPoolSize() { |
||||
return getThreadPoolExecutor().getPoolSize(); |
||||
} |
||||
|
||||
/** |
||||
* Return the number of currently active threads. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#getActiveCount() |
||||
*/ |
||||
public int getActiveCount() { |
||||
return getThreadPoolExecutor().getActiveCount(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Calls {@code shutdown} when the BeanFactory destroys |
||||
* the task executor instance. |
||||
* @see #shutdown() |
||||
*/ |
||||
public void destroy() { |
||||
shutdown(); |
||||
} |
||||
|
||||
/** |
||||
* Perform a shutdown on the ThreadPoolExecutor. |
||||
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdown() |
||||
*/ |
||||
public void shutdown() { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Shutting down ThreadPoolExecutor" + (this.beanName != null ? " '" + this.beanName + "'" : "")); |
||||
} |
||||
if (this.waitForTasksToCompleteOnShutdown) { |
||||
this.threadPoolExecutor.shutdown(); |
||||
} |
||||
else { |
||||
this.threadPoolExecutor.shutdownNow(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
|
||||
/** |
||||
* |
||||
* Scheduling convenience classes for the |
||||
* <a href="http://dcl.mathcs.emory.edu/util/backport-util-concurrent/">JSR-166 backport</a> |
||||
* Executor mechanism, allowing to set up a ThreadPoolExecutor |
||||
* as a TaskExecutor-compliant bean in a Spring context. |
||||
* |
||||
*/ |
||||
package org.springframework.scheduling.backportconcurrent; |
||||
|
||||
@ -1,78 +0,0 @@
@@ -1,78 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import java.util.TimerTask; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Simple {@link java.util.TimerTask} adapter that delegates to a |
||||
* given {@link Runnable}. |
||||
* |
||||
* <p>This is often preferable to deriving from TimerTask, to be able to |
||||
* implement an interface rather than extend an abstract base class. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 1.2.4 |
||||
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent} |
||||
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService} |
||||
*/ |
||||
@Deprecated |
||||
public class DelegatingTimerTask extends TimerTask { |
||||
|
||||
private static final Log logger = LogFactory.getLog(DelegatingTimerTask.class); |
||||
|
||||
private final Runnable delegate; |
||||
|
||||
|
||||
/** |
||||
* Create a new DelegatingTimerTask. |
||||
* @param delegate the Runnable implementation to delegate to |
||||
*/ |
||||
public DelegatingTimerTask(Runnable delegate) { |
||||
Assert.notNull(delegate, "Delegate must not be null"); |
||||
this.delegate = delegate; |
||||
} |
||||
|
||||
/** |
||||
* Return the wrapped Runnable implementation. |
||||
*/ |
||||
public final Runnable getDelegate() { |
||||
return this.delegate; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Delegates execution to the underlying Runnable, catching any exception |
||||
* or error thrown in order to continue scheduled execution. |
||||
*/ |
||||
@Override |
||||
public void run() { |
||||
try { |
||||
this.delegate.run(); |
||||
} |
||||
catch (Throwable ex) { |
||||
logger.error("Unexpected exception thrown from Runnable: " + this.delegate, ex); |
||||
// Do not throw the exception, else the main loop of the Timer might stop!
|
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,68 +0,0 @@
@@ -1,68 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import java.util.TimerTask; |
||||
|
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.scheduling.support.MethodInvokingRunnable; |
||||
|
||||
/** |
||||
* {@link FactoryBean} that exposes a {@link TimerTask} object which |
||||
* delegates job execution to a specified (static or non-static) method. |
||||
* Avoids the need to implement a one-line TimerTask that just invokes |
||||
* an existing business method. |
||||
* |
||||
* <p>Derives from {@link MethodInvokingRunnable} to share common properties |
||||
* and behavior, effectively providing a TimerTask adapter for it. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 19.02.2004 |
||||
* @see DelegatingTimerTask |
||||
* @see ScheduledTimerTask#setTimerTask |
||||
* @see ScheduledTimerTask#setRunnable |
||||
* @see org.springframework.scheduling.support.MethodInvokingRunnable |
||||
* @see org.springframework.beans.factory.config.MethodInvokingFactoryBean |
||||
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent} |
||||
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService} |
||||
*/ |
||||
@Deprecated |
||||
public class MethodInvokingTimerTaskFactoryBean extends MethodInvokingRunnable implements FactoryBean<TimerTask> { |
||||
|
||||
private TimerTask timerTask; |
||||
|
||||
|
||||
@Override |
||||
public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException { |
||||
super.afterPropertiesSet(); |
||||
this.timerTask = new DelegatingTimerTask(this); |
||||
} |
||||
|
||||
|
||||
public TimerTask getObject() { |
||||
return this.timerTask; |
||||
} |
||||
|
||||
public Class<TimerTask> getObjectType() { |
||||
return TimerTask.class; |
||||
} |
||||
|
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
@ -1,226 +0,0 @@
@@ -1,226 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import java.util.TimerTask; |
||||
|
||||
/** |
||||
* JavaBean that describes a scheduled {@link TimerTask}, consisting of the |
||||
* {@link TimerTask} itself or a {@link Runnable} to create a {@link TimerTask} |
||||
* for and a delay plus period. The period needs to be specified; there is |
||||
* no point in a default for it. |
||||
* |
||||
* <p>The JDK's {@link java.util.Timer} facility does not offer sophisticated |
||||
* scheduling options such as cron expressions. Consider using Quartz for |
||||
* such advanced needs. |
||||
* |
||||
* <p>Note that the {@link java.util.Timer} mechanism uses a {@link TimerTask} |
||||
* instance that is shared between repeated executions, in contrast to Quartz |
||||
* which creates a new Job instance for each execution. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 19.02.2004 |
||||
* @see java.util.TimerTask |
||||
* @see java.util.Timer#schedule(TimerTask, long, long) |
||||
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long) |
||||
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent} |
||||
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService} |
||||
*/ |
||||
@Deprecated |
||||
public class ScheduledTimerTask { |
||||
|
||||
private TimerTask timerTask; |
||||
|
||||
private long delay = 0; |
||||
|
||||
private long period = -1; |
||||
|
||||
private boolean fixedRate = false; |
||||
|
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask, |
||||
* to be populated via bean properties. |
||||
* @see #setTimerTask |
||||
* @see #setDelay |
||||
* @see #setPeriod |
||||
* @see #setFixedRate |
||||
*/ |
||||
public ScheduledTimerTask() { |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask, with default |
||||
* one-time execution without delay. |
||||
* @param timerTask the TimerTask to schedule |
||||
*/ |
||||
public ScheduledTimerTask(TimerTask timerTask) { |
||||
this.timerTask = timerTask; |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask, with default |
||||
* one-time execution with the given delay. |
||||
* @param timerTask the TimerTask to schedule |
||||
* @param delay the delay before starting the task for the first time (ms) |
||||
*/ |
||||
public ScheduledTimerTask(TimerTask timerTask, long delay) { |
||||
this.timerTask = timerTask; |
||||
this.delay = delay; |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask. |
||||
* @param timerTask the TimerTask to schedule |
||||
* @param delay the delay before starting the task for the first time (ms) |
||||
* @param period the period between repeated task executions (ms) |
||||
* @param fixedRate whether to schedule as fixed-rate execution |
||||
*/ |
||||
public ScheduledTimerTask(TimerTask timerTask, long delay, long period, boolean fixedRate) { |
||||
this.timerTask = timerTask; |
||||
this.delay = delay; |
||||
this.period = period; |
||||
this.fixedRate = fixedRate; |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask, with default |
||||
* one-time execution without delay. |
||||
* @param timerTask the Runnable to schedule as TimerTask |
||||
*/ |
||||
public ScheduledTimerTask(Runnable timerTask) { |
||||
setRunnable(timerTask); |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask, with default |
||||
* one-time execution with the given delay. |
||||
* @param timerTask the Runnable to schedule as TimerTask |
||||
* @param delay the delay before starting the task for the first time (ms) |
||||
*/ |
||||
public ScheduledTimerTask(Runnable timerTask, long delay) { |
||||
setRunnable(timerTask); |
||||
this.delay = delay; |
||||
} |
||||
|
||||
/** |
||||
* Create a new ScheduledTimerTask. |
||||
* @param timerTask the Runnable to schedule as TimerTask |
||||
* @param delay the delay before starting the task for the first time (ms) |
||||
* @param period the period between repeated task executions (ms) |
||||
* @param fixedRate whether to schedule as fixed-rate execution |
||||
*/ |
||||
public ScheduledTimerTask(Runnable timerTask, long delay, long period, boolean fixedRate) { |
||||
setRunnable(timerTask); |
||||
this.delay = delay; |
||||
this.period = period; |
||||
this.fixedRate = fixedRate; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Set the Runnable to schedule as TimerTask. |
||||
* @see DelegatingTimerTask |
||||
*/ |
||||
public void setRunnable(Runnable timerTask) { |
||||
this.timerTask = new DelegatingTimerTask(timerTask); |
||||
} |
||||
|
||||
/** |
||||
* Set the TimerTask to schedule. |
||||
*/ |
||||
public void setTimerTask(TimerTask timerTask) { |
||||
this.timerTask = timerTask; |
||||
} |
||||
|
||||
/** |
||||
* Return the TimerTask to schedule. |
||||
*/ |
||||
public TimerTask getTimerTask() { |
||||
return this.timerTask; |
||||
} |
||||
|
||||
/** |
||||
* Set the delay before starting the task for the first time, |
||||
* in milliseconds. Default is 0, immediately starting the |
||||
* task after successful scheduling. |
||||
*/ |
||||
public void setDelay(long delay) { |
||||
this.delay = delay; |
||||
} |
||||
|
||||
/** |
||||
* Return the delay before starting the job for the first time. |
||||
*/ |
||||
public long getDelay() { |
||||
return this.delay; |
||||
} |
||||
|
||||
/** |
||||
* Set the period between repeated task executions, in milliseconds. |
||||
* <p>Default is -1, leading to one-time execution. In case of a positive |
||||
* value, the task will be executed repeatedly, with the given interval |
||||
* inbetween executions. |
||||
* <p>Note that the semantics of the period value vary between fixed-rate |
||||
* and fixed-delay execution. |
||||
* <p><b>Note:</b> A period of 0 (for example as fixed delay) is <i>not</i> |
||||
* supported, simply because {@code java.util.Timer} itself does not |
||||
* support it. Hence a value of 0 will be treated as one-time execution; |
||||
* however, that value should never be specified explicitly in the first place! |
||||
* @see #setFixedRate |
||||
* @see #isOneTimeTask() |
||||
* @see java.util.Timer#schedule(TimerTask, long, long) |
||||
*/ |
||||
public void setPeriod(long period) { |
||||
this.period = period; |
||||
} |
||||
|
||||
/** |
||||
* Return the period between repeated task executions. |
||||
*/ |
||||
public long getPeriod() { |
||||
return this.period; |
||||
} |
||||
|
||||
/** |
||||
* Is this task only ever going to execute once? |
||||
* @return {@code true} if this task is only ever going to execute once |
||||
* @see #getPeriod() |
||||
*/ |
||||
public boolean isOneTimeTask() { |
||||
return (this.period <= 0); |
||||
} |
||||
|
||||
/** |
||||
* Set whether to schedule as fixed-rate execution, rather than |
||||
* fixed-delay execution. Default is "false", that is, fixed delay. |
||||
* <p>See Timer javadoc for details on those execution modes. |
||||
* @see java.util.Timer#schedule(TimerTask, long, long) |
||||
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long) |
||||
*/ |
||||
public void setFixedRate(boolean fixedRate) { |
||||
this.fixedRate = fixedRate; |
||||
} |
||||
|
||||
/** |
||||
* Return whether to schedule as fixed-rate execution. |
||||
*/ |
||||
public boolean isFixedRate() { |
||||
return this.fixedRate; |
||||
} |
||||
|
||||
} |
||||
@ -1,169 +0,0 @@
@@ -1,169 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import java.util.Timer; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.beans.factory.BeanNameAware; |
||||
import org.springframework.beans.factory.DisposableBean; |
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.beans.factory.InitializingBean; |
||||
import org.springframework.util.ObjectUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* FactoryBean that sets up a {@link java.util.Timer} and exposes it for bean references. |
||||
* |
||||
* <p>Allows for registration of {@link ScheduledTimerTask ScheduledTimerTasks}, |
||||
* automatically starting the {@link Timer} on initialization and cancelling it |
||||
* on destruction of the context. In scenarios that just require static registration |
||||
* of tasks at startup, there is no need to access the {@link Timer} instance itself |
||||
* in application code at all. |
||||
* |
||||
* <p>Note that the {@link Timer} mechanism uses a {@link java.util.TimerTask} |
||||
* instance that is shared between repeated executions, in contrast to Quartz |
||||
* which creates a new Job instance for each execution. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 19.02.2004 |
||||
* @see ScheduledTimerTask |
||||
* @see java.util.Timer |
||||
* @see java.util.TimerTask |
||||
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent} |
||||
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService} |
||||
*/ |
||||
@Deprecated |
||||
public class TimerFactoryBean implements FactoryBean<Timer>, BeanNameAware, InitializingBean, DisposableBean { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private ScheduledTimerTask[] scheduledTimerTasks; |
||||
|
||||
private boolean daemon = false; |
||||
|
||||
private String beanName; |
||||
|
||||
private Timer timer; |
||||
|
||||
|
||||
/** |
||||
* Register a list of ScheduledTimerTask objects with the Timer that |
||||
* this FactoryBean creates. Depending on each SchedulerTimerTask's |
||||
* settings, it will be registered via one of Timer's schedule methods. |
||||
* @see java.util.Timer#schedule(java.util.TimerTask, long) |
||||
* @see java.util.Timer#schedule(java.util.TimerTask, long, long) |
||||
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long) |
||||
*/ |
||||
public void setScheduledTimerTasks(ScheduledTimerTask[] scheduledTimerTasks) { |
||||
this.scheduledTimerTasks = scheduledTimerTasks; |
||||
} |
||||
|
||||
/** |
||||
* Set whether the timer should use a daemon thread, |
||||
* just executing as long as the application itself is running. |
||||
* <p>Default is "false": The timer will automatically get cancelled on |
||||
* destruction of this FactoryBean. Hence, if the application shuts down, |
||||
* tasks will by default finish their execution. Specify "true" for eager |
||||
* shutdown of threads that execute tasks. |
||||
* @see java.util.Timer#Timer(boolean) |
||||
*/ |
||||
public void setDaemon(boolean daemon) { |
||||
this.daemon = daemon; |
||||
} |
||||
|
||||
public void setBeanName(String beanName) { |
||||
this.beanName = beanName; |
||||
} |
||||
|
||||
|
||||
public void afterPropertiesSet() { |
||||
logger.info("Initializing Timer"); |
||||
this.timer = createTimer(this.beanName, this.daemon); |
||||
|
||||
// Register specified ScheduledTimerTasks, if necessary.
|
||||
if (!ObjectUtils.isEmpty(this.scheduledTimerTasks)) { |
||||
registerTasks(this.scheduledTimerTasks, this.timer); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create a new Timer instance. Called by {@code afterPropertiesSet}. |
||||
* Can be overridden in subclasses to provide custom Timer subclasses. |
||||
* @param name the desired name of the Timer's associated thread |
||||
* @param daemon whether to create a Timer that runs as daemon thread |
||||
* @return a new Timer instance |
||||
* @see #afterPropertiesSet() |
||||
* @see java.util.Timer#Timer(boolean) |
||||
*/ |
||||
protected Timer createTimer(String name, boolean daemon) { |
||||
if (StringUtils.hasText(name)) { |
||||
return new Timer(name, daemon); |
||||
} |
||||
else { |
||||
return new Timer(daemon); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Register the specified {@link ScheduledTimerTask ScheduledTimerTasks} |
||||
* on the given {@link Timer}. |
||||
* @param tasks the specified ScheduledTimerTasks (never empty) |
||||
* @param timer the Timer to register the tasks on. |
||||
*/ |
||||
protected void registerTasks(ScheduledTimerTask[] tasks, Timer timer) { |
||||
for (ScheduledTimerTask task : tasks) { |
||||
if (task.isOneTimeTask()) { |
||||
timer.schedule(task.getTimerTask(), task.getDelay()); |
||||
} |
||||
else { |
||||
if (task.isFixedRate()) { |
||||
timer.scheduleAtFixedRate(task.getTimerTask(), task.getDelay(), task.getPeriod()); |
||||
} |
||||
else { |
||||
timer.schedule(task.getTimerTask(), task.getDelay(), task.getPeriod()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public Timer getObject() { |
||||
return this.timer; |
||||
} |
||||
|
||||
public Class<? extends Timer> getObjectType() { |
||||
return Timer.class; |
||||
} |
||||
|
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Cancel the Timer on bean factory shutdown, stopping all scheduled tasks. |
||||
* @see java.util.Timer#cancel() |
||||
*/ |
||||
public void destroy() { |
||||
logger.info("Cancelling Timer"); |
||||
this.timer.cancel(); |
||||
} |
||||
|
||||
} |
||||
@ -1,184 +0,0 @@
@@ -1,184 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import java.util.Timer; |
||||
import java.util.concurrent.Callable; |
||||
import java.util.concurrent.Future; |
||||
import java.util.concurrent.FutureTask; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.beans.factory.BeanNameAware; |
||||
import org.springframework.beans.factory.DisposableBean; |
||||
import org.springframework.beans.factory.InitializingBean; |
||||
import org.springframework.scheduling.SchedulingTaskExecutor; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* {@link org.springframework.core.task.TaskExecutor} implementation that uses a |
||||
* single {@link Timer} for executing all tasks, effectively resulting in |
||||
* serialized asynchronous execution on a single thread. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 2.0 |
||||
* @see java.util.Timer |
||||
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent} |
||||
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService} |
||||
*/ |
||||
@Deprecated |
||||
public class TimerTaskExecutor implements SchedulingTaskExecutor, BeanNameAware, InitializingBean, DisposableBean { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private Timer timer; |
||||
|
||||
private long delay = 0; |
||||
|
||||
private String beanName; |
||||
|
||||
private boolean timerInternal = false; |
||||
|
||||
|
||||
/** |
||||
* Create a new TimerTaskExecutor that needs to be further configured and initialized. |
||||
* @see #setTimer |
||||
* @see #afterPropertiesSet |
||||
*/ |
||||
public TimerTaskExecutor() { |
||||
} |
||||
|
||||
/** |
||||
* Create a new TimerTaskExecutor for the given {@link Timer}. |
||||
* @param timer the {@link Timer} to wrap |
||||
*/ |
||||
public TimerTaskExecutor(Timer timer) { |
||||
Assert.notNull(timer, "Timer must not be null"); |
||||
this.timer = timer; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Set the {@link Timer} to use for this {@link TimerTaskExecutor}, for example |
||||
* a shared {@link Timer} instance defined by a {@link TimerFactoryBean}. |
||||
* <p>If not specified, a default internal {@link Timer} instance will be used. |
||||
* @param timer the {@link Timer} to use for this {@link TimerTaskExecutor} |
||||
* @see TimerFactoryBean |
||||
*/ |
||||
public void setTimer(Timer timer) { |
||||
this.timer = timer; |
||||
} |
||||
|
||||
/** |
||||
* Set the delay to use for scheduling tasks passed into the plain |
||||
* {@link #execute(Runnable)} method. Default is 0. |
||||
* <p>Note that calls to {@link #execute(Runnable, long)} will use the |
||||
* given timeout as delay if it is lower than the general delay. |
||||
* @param delay the delay in milliseconds before the task is to be executed |
||||
*/ |
||||
public void setDelay(long delay) { |
||||
this.delay = delay; |
||||
} |
||||
|
||||
public void setBeanName(String beanName) { |
||||
this.beanName = beanName; |
||||
} |
||||
|
||||
|
||||
public void afterPropertiesSet() { |
||||
if (this.timer == null) { |
||||
logger.info("Initializing Timer"); |
||||
this.timer = createTimer(); |
||||
this.timerInternal = true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@link Timer} instance. Called by {@code afterPropertiesSet} |
||||
* if no {@link Timer} has been specified explicitly. |
||||
* <p>The default implementation creates a plain non-daemon {@link Timer}. |
||||
* If overridden, subclasses must take care to ensure that a non-null |
||||
* {@link Timer} is returned from the execution of this method. |
||||
* @see #afterPropertiesSet |
||||
* @see java.util.Timer#Timer(String, boolean) |
||||
*/ |
||||
protected Timer createTimer() { |
||||
if (StringUtils.hasText(this.beanName)) { |
||||
return new Timer(this.beanName); |
||||
} |
||||
else { |
||||
return new Timer(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the underlying Timer behind this TimerTaskExecutor. |
||||
*/ |
||||
protected final Timer getTimer() { |
||||
Assert.notNull(this.timer, "Timer not initialized yet"); |
||||
return this.timer; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Schedules the given {@link Runnable} on this executor's {@link Timer} instance, |
||||
* wrapping it in a {@link DelegatingTimerTask}. |
||||
* @param task the task to be executed |
||||
*/ |
||||
public void execute(Runnable task) { |
||||
getTimer().schedule(new DelegatingTimerTask(task), this.delay); |
||||
} |
||||
|
||||
public void execute(Runnable task, long startTimeout) { |
||||
long actualDelay = (startTimeout < this.delay ? startTimeout : this.delay); |
||||
getTimer().schedule(new DelegatingTimerTask(task), actualDelay); |
||||
} |
||||
|
||||
public Future<?> submit(Runnable task) { |
||||
FutureTask<Object> future = new FutureTask<Object>(task, null); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
public <T> Future<T> submit(Callable<T> task) { |
||||
FutureTask<T> future = new FutureTask<T>(task); |
||||
execute(future); |
||||
return future; |
||||
} |
||||
|
||||
/** |
||||
* This task executor prefers short-lived work units. |
||||
*/ |
||||
public boolean prefersShortLivedTasks() { |
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Cancel the {@link Timer} on bean factory shutdown, stopping all scheduled tasks. |
||||
* @see java.util.Timer#cancel() |
||||
*/ |
||||
public void destroy() { |
||||
if (this.timerInternal) { |
||||
logger.info("Cancelling Timer"); |
||||
this.timer.cancel(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
|
||||
/** |
||||
* |
||||
* Scheduling convenience classes for the JDK Timer, |
||||
* allowing to set up Timers and ScheduledTimerTasks |
||||
* as beans in a Spring context. |
||||
* |
||||
*/ |
||||
package org.springframework.scheduling.timer; |
||||
|
||||
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.backportconcurrent; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.springframework.core.task.NoOpRunnable; |
||||
|
||||
/** |
||||
* @author Rick Evans |
||||
* @author Juergen Hoeller |
||||
*/ |
||||
@Deprecated |
||||
public class ConcurrentTaskExecutorTests extends TestCase { |
||||
|
||||
public void testZeroArgCtorResultsInDefaultTaskExecutorBeingUsed() throws Exception { |
||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(); |
||||
// must not throw a NullPointerException
|
||||
executor.execute(new NoOpRunnable()); |
||||
} |
||||
|
||||
public void testPassingNullExecutorToCtorResultsInDefaultTaskExecutorBeingUsed() throws Exception { |
||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(null); |
||||
// must not throw a NullPointerException
|
||||
executor.execute(new NoOpRunnable()); |
||||
} |
||||
|
||||
public void testPassingNullExecutorToSetterResultsInDefaultTaskExecutorBeingUsed() throws Exception { |
||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(); |
||||
executor.setConcurrentExecutor(null); |
||||
// must not throw a NullPointerException
|
||||
executor.execute(new NoOpRunnable()); |
||||
} |
||||
|
||||
} |
||||
@ -1,133 +0,0 @@
@@ -1,133 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import static org.hamcrest.Matchers.instanceOf; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Timer; |
||||
import java.util.TimerTask; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.springframework.tests.context.TestMethodInvokingTask; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @since 20.02.2004 |
||||
*/ |
||||
@Deprecated |
||||
public class TimerSupportTests extends TestCase { |
||||
|
||||
public void testTimerFactoryBean() throws Exception { |
||||
final TestTimerTask timerTask0 = new TestTimerTask(); |
||||
|
||||
TestMethodInvokingTask task1 = new TestMethodInvokingTask(); |
||||
MethodInvokingTimerTaskFactoryBean mittfb = new MethodInvokingTimerTaskFactoryBean(); |
||||
mittfb.setTargetObject(task1); |
||||
mittfb.setTargetMethod("doSomething"); |
||||
mittfb.afterPropertiesSet(); |
||||
final TimerTask timerTask1 = mittfb.getObject(); |
||||
|
||||
final TestRunnable timerTask2 = new TestRunnable(); |
||||
|
||||
ScheduledTimerTask[] tasks = new ScheduledTimerTask[3]; |
||||
tasks[0] = new ScheduledTimerTask(timerTask0, 0, 10, false); |
||||
tasks[1] = new ScheduledTimerTask(timerTask1, 10, 20, true); |
||||
tasks[2] = new ScheduledTimerTask(timerTask2, 20); |
||||
|
||||
final List<Boolean> success = new ArrayList<Boolean>(3); |
||||
final Timer timer = new Timer(true) { |
||||
@Override |
||||
public void schedule(TimerTask task, long delay, long period) { |
||||
if (task == timerTask0 && delay == 0 && period == 10) { |
||||
success.add(Boolean.TRUE); |
||||
} |
||||
} |
||||
@Override |
||||
public void scheduleAtFixedRate(TimerTask task, long delay, long period) { |
||||
if (task == timerTask1 && delay == 10 && period == 20) { |
||||
success.add(Boolean.TRUE); |
||||
} |
||||
} |
||||
@Override |
||||
public void schedule(TimerTask task, long delay) { |
||||
if (task instanceof DelegatingTimerTask && delay == 20) { |
||||
success.add(Boolean.TRUE); |
||||
} |
||||
} |
||||
@Override |
||||
public void cancel() { |
||||
success.add(Boolean.TRUE); |
||||
} |
||||
}; |
||||
|
||||
TimerFactoryBean timerFactoryBean = new TimerFactoryBean() { |
||||
@Override |
||||
protected Timer createTimer(String name, boolean daemon) { |
||||
return timer; |
||||
} |
||||
}; |
||||
try { |
||||
timerFactoryBean.setScheduledTimerTasks(tasks); |
||||
timerFactoryBean.afterPropertiesSet(); |
||||
assertThat(timerFactoryBean.getObject(), instanceOf(Timer.class)); |
||||
timerTask0.run(); |
||||
timerTask1.run(); |
||||
timerTask2.run(); |
||||
} |
||||
finally { |
||||
timerFactoryBean.destroy(); |
||||
} |
||||
|
||||
assertTrue("Correct Timer invocations", success.size() == 4); |
||||
assertTrue("TimerTask0 works", timerTask0.counter == 1); |
||||
assertTrue("TimerTask1 works", task1.counter == 1); |
||||
assertTrue("TimerTask2 works", timerTask2.counter == 1); |
||||
} |
||||
|
||||
public void testPlainTimerFactoryBean() { |
||||
TimerFactoryBean tfb = new TimerFactoryBean(); |
||||
tfb.afterPropertiesSet(); |
||||
tfb.destroy(); |
||||
} |
||||
|
||||
|
||||
private static class TestTimerTask extends TimerTask { |
||||
|
||||
private int counter = 0; |
||||
|
||||
@Override |
||||
public void run() { |
||||
counter++; |
||||
} |
||||
} |
||||
|
||||
|
||||
private static class TestRunnable implements Runnable { |
||||
|
||||
private int counter = 0; |
||||
|
||||
@Override |
||||
public void run() { |
||||
counter++; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,190 +0,0 @@
@@ -1,190 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2012 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.scheduling.timer; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
import java.util.Timer; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* Unit tests for the {@link TimerTaskExecutor} class. |
||||
* |
||||
* @author Rick Evans |
||||
* @author Chris Beams |
||||
*/ |
||||
@Deprecated |
||||
public final class TimerTaskExecutorTests { |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void testExecuteChokesWithNullTimer() throws Exception { |
||||
TimerTaskExecutor executor = new TimerTaskExecutor(); |
||||
executor.execute(new NoOpRunnable()); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void testExecuteChokesWithNullTask() throws Exception { |
||||
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); |
||||
executor.execute(null); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void testExecuteChokesWithNegativeDelay() throws Exception { |
||||
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); |
||||
executor.setDelay(-10); |
||||
executor.execute(new NoOpRunnable()); |
||||
} |
||||
|
||||
@Test |
||||
public void testExecuteReallyDoesScheduleTheSuppliedTask() throws Exception { |
||||
final Object monitor = new Object(); |
||||
|
||||
RunAwareRunnable task = new RunAwareRunnable(monitor); |
||||
|
||||
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); |
||||
executor.execute(task); |
||||
|
||||
synchronized (monitor) { |
||||
monitor.wait(5000); |
||||
} |
||||
|
||||
assertTrue("Supplied task (a Runnable) is not being invoked.", task.isRunWasCalled()); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void testCtorWithNullTimer() throws Exception { |
||||
new TimerTaskExecutor(null); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreateTimerMethodIsCalledIfNoTimerIsExplicitlySupplied() throws Exception { |
||||
CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor(); |
||||
executor.afterPropertiesSet(); |
||||
assertTrue("If no Timer is set explicitly, then the protected createTimer() " + |
||||
"method must be called to create the Timer (it obviously isn't being called).", |
||||
executor.isCreateTimerWasCalled()); |
||||
} |
||||
|
||||
@Test |
||||
public void testCreateTimerMethodIsNotCalledIfTimerIsExplicitlySupplied() throws Exception { |
||||
CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor(); |
||||
executor.setTimer(new Timer()); |
||||
executor.afterPropertiesSet(); |
||||
assertFalse("If a Timer is set explicitly, then the protected createTimer() " + |
||||
"method must not be called to create the Timer (it obviously is being called, in error).", |
||||
executor.isCreateTimerWasCalled()); |
||||
} |
||||
|
||||
@Test |
||||
public void testThatTheDestroyCallbackCancelsTheTimerIfNoTimerIsExplicitlySupplied() throws Exception { |
||||
|
||||
final CancelAwareTimer timer = new CancelAwareTimer(); |
||||
|
||||
TimerTaskExecutor executor = new TimerTaskExecutor() { |
||||
|
||||
@Override |
||||
protected Timer createTimer() { |
||||
return timer; |
||||
} |
||||
}; |
||||
executor.afterPropertiesSet(); |
||||
executor.destroy(); |
||||
assertTrue("When the Timer used is created by the TimerTaskExecutor because " + |
||||
"no Timer was set explicitly, then the destroy() callback must cancel() said Timer (it obviously isn't doing this).", |
||||
timer.isCancelWasCalled()); |
||||
} |
||||
|
||||
@Test |
||||
public void testThatTheDestroyCallbackDoesNotCancelTheTimerIfTheTimerWasSuppliedExplictly() throws Exception { |
||||
TimerTaskExecutor executor = new TimerTaskExecutor(); |
||||
CancelAwareTimer timer = new CancelAwareTimer(); |
||||
executor.setTimer(timer); |
||||
executor.afterPropertiesSet(); |
||||
executor.destroy(); |
||||
assertFalse("When the Timer used is not created by the TimerTaskExecutor because " + |
||||
"it Timer was set explicitly, then the destroy() callback must NOT cancel() said Timer (it obviously is, in error).", |
||||
timer.isCancelWasCalled()); |
||||
} |
||||
|
||||
|
||||
private final static class CreationAwareTimerTaskExecutor extends TimerTaskExecutor { |
||||
|
||||
private boolean createTimerWasCalled = false; |
||||
|
||||
|
||||
public boolean isCreateTimerWasCalled() { |
||||
return this.createTimerWasCalled; |
||||
} |
||||
|
||||
@Override |
||||
protected Timer createTimer() { |
||||
this.createTimerWasCalled = true; |
||||
return super.createTimer(); |
||||
} |
||||
|
||||
} |
||||
|
||||
private static class CancelAwareTimer extends Timer { |
||||
|
||||
private boolean cancelWasCalled; |
||||
|
||||
|
||||
public boolean isCancelWasCalled() { |
||||
return this.cancelWasCalled; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void cancel() { |
||||
this.cancelWasCalled = true; |
||||
super.cancel(); |
||||
} |
||||
} |
||||
|
||||
private static class RunAwareRunnable implements Runnable { |
||||
private boolean runWasCalled; |
||||
private final Object monitor; |
||||
|
||||
public RunAwareRunnable(Object monitor) { |
||||
this.monitor = monitor; |
||||
} |
||||
|
||||
|
||||
public boolean isRunWasCalled() { |
||||
return this.runWasCalled; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void run() { |
||||
this.runWasCalled = true; |
||||
synchronized (monitor) { |
||||
monitor.notifyAll(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static final class NoOpRunnable implements Runnable { |
||||
|
||||
@Override |
||||
public void run() { |
||||
// explicit no-op
|
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue