以下是Spring官方文档中关于异步方法(@Async)、线程池、定时任务的部分,英文文档的描述比较准确且深入。
34. Task Execution and Scheduling
The Spring Framework provides abstractions for asynchronous execution and scheduling oftasks with theTaskExecutor
andTaskScheduler
interfaces, respectively. Spring alsofeatures implementations of those interfaces that support thread pools or delegation toCommonJ within an application server environment. Ultimately the use of theseimplementations behind the common interfaces abstracts away the differences between JavaSE 5, Java SE 6 and Java EE environments.
Spring also features integration classes for supporting scheduling with the Timer
,part of the JDK since 1.3, and the Quartz Scheduler ( http://quartz-scheduler.org).Both of those schedulers are set up using a FactoryBean
with optional references toTimer
orTrigger
instances, respectively. Furthermore, a convenience class for boththe Quartz Scheduler and theTimer
is available that allows you to invoke a method ofan existing target object (analogous to the normalMethodInvokingFactoryBean
operation).
34.2 The Spring TaskExecutor abstraction
Spring 2.0 introduces a new abstraction for dealing with executors. Executors are theJava 5 name for the concept of thread pools. The "executor" naming is due to the factthat there is no guarantee that the underlying implementation is actually a pool; anexecutor may be single-threaded or even synchronous. Spring’s abstraction hidesimplementation details between Java SE 1.4, Java SE 5 and Java EE environments.
Spring’s TaskExecutor
interface is identical to thejava.util.concurrent.Executor
interface. In fact, its primary reason for existence was to abstract away the need forJava 5 when using thread pools. The interface has a single methodexecute(Runnabletask)
that accepts a task for execution based on the semantics and configuration of thethread pool.
The TaskExecutor
was originally created to give other Spring components an abstractionfor thread pooling where needed. Components such as theApplicationEventMulticaster
,JMS’sAbstractMessageListenerContainer
, and Quartz integration all use theTaskExecutor
abstraction to pool threads. However, if your beans need thread poolingbehavior, it is possible to use this abstraction for your own needs.
There are a number of pre-built implementations of TaskExecutor
included with theSpring distribution. In all likelihood, you shouldn’t ever need to implement your own.
SimpleAsyncTaskExecutor
This implementation does not reuse any threads, rather it starts up a new threadfor each invocation. However, it does support a concurrency limit which will blockany invocations that are over the limit until a slot has been freed up. If youare looking for true pooling, see the discussions ofSimpleThreadPoolTaskExecutor
andThreadPoolTaskExecutor
below.SyncTaskExecutor
This implementation doesn’t execute invocations asynchronously. Instead, eachinvocation takes place in the calling thread. It is primarily used in situationswhere multi-threading isn’t necessary such as simple test cases.ConcurrentTaskExecutor
This implementation is an adapter for ajava.util.concurrent.Executor
object.There is an alternative,ThreadPoolTaskExecutor
, that exposes theExecutor
configuration parameters as bean properties. It is rare to need to use theConcurrentTaskExecutor
, but if theThreadPoolTaskExecutor
isn’t flexibleenough for your needs, theConcurrentTaskExecutor
is an alternative.SimpleThreadPoolTaskExecutor
This implementation is actually a subclass of Quartz’sSimpleThreadPool
whichlistens to Spring’s lifecycle callbacks. This is typically used when you have athread pool that may need to be shared by both Quartz and non-Quartz components.ThreadPoolTaskExecutor
This implementation is the most commonly used one. It exposes bean properties forconfiguring ajava.util.concurrent.ThreadPoolExecutor
and wraps it in aTaskExecutor
.If you need to adapt to a different kind ofjava.util.concurrent.Executor
, it isrecommended that you use aConcurrentTaskExecutor
instead.-
WorkManagerTaskExecutor
This implementation uses the CommonJ
WorkManager
as its backing implementation and isthe central convenience class for setting up a CommonJWorkManager
reference in a Springcontext. Similar to theSimpleThreadPoolTaskExecutor
, this class implements theWorkManager
interface and therefore can be used directly as aWorkManager
as well.
34.2.2 Using a TaskExecutor
Spring’s TaskExecutor
implementations are used as simple JavaBeans. In the examplebelow, we define a bean that uses theThreadPoolTaskExecutor
to asynchronously printout a set of messages.
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public Mes