您的位置:首页 > 编程语言 > Java开发

SpringTaskExecutor介绍

2014-12-22 10:24 393 查看


23.4. Spring
TaskExecutor
抽象

Spring 2.0 为执行器(Executor)处理引入了一个新的抽象层。Executor是Java 5的名词,用来表示线程池的概念。 之所以用这个奇怪的名词,是因为实际上不能保证底层实现的确是一个池。实际上,很多情况下,executor只是单线程。 Spring的抽象层帮助你把线程池引入到Java 1.3和1.4环境中,同时隐藏了 1.3, 1.4, 5, 和 Java EE环境中线程池实现的差异。


23.4.1.
TaskExecutor
接口

Spring的
TaskExecutor
接口等同于
java.util.concurrent.Executor
接口。 实际上,它存在的主要原因是为了在使用线程池的时候,将对Java 5的依赖抽象出来。 这个接口只有一个方法
execute(Runnable
task)
,它根据线程池的语义和配置,来接受一个执行任务。

最初创建
TaskExecutor
是为了在需要时给其他Spring组件提供一个线程池的抽象。 例如
ApplicationEventMulticaster
组件、JMS的
AbstractMessageListenerContainer
和对Quartz的整合都使用了
TaskExecutor
抽象来提供线程池。
当然,如果你的bean需要线程池行为,你也可以使用这个抽象层。


23.4.2.
TaskExecutor
类型

在Spring发行包中预定义了一些
TaskExecutor
实现。有了它们,你甚至不需要再自行实现了。

SimpleAsyncTaskExecutor


这个实现不重用任何线程,或者说它每次调用都启动一个新线程。但是,它还是支持对并发总数设限,当超过线程并发总数限制时,阻塞新的调用,直到有位置被释放。如果你需要真正的池,请继续往下看。

SyncTaskExecutor


这个实现不会异步执行。相反,每次调用都在发起调用的线程中执行。它的主要用处是在不需要多线程的时候,比如简单的test case。

ConcurrentTaskExecutor


这个实现是对Java 5
java.util.concurrent.Executor
类的包装。有另一个备选,
ThreadPoolTaskExecutor
类,它暴露了
Executor
的配置参数作为bean属性。很少需要使用
ConcurrentTaskExecutor
,
但是如果
ThreadPoolTaskExecutor
不敷所需,
ConcurrentTaskExecutor
是另外一个备选。

SimpleThreadPoolTaskExecutor


这个实现实际上是Quartz的
SimpleThreadPool
类的子类,它会监听Spring的生命周期回调。当你有线程池,需要在Quartz和非Quartz组件中共用时,这是它的典型用处。

ThreadPoolTaskExecutor


它不支持任何对
java.util.concurrent
包的替换或者下行移植。Doug Lea和Dawid Kurzyniec对
java.util.concurrent
的实现都采用了不同的包结构,导致它们无法正确运行。

这个实现只能在Java 5环境中使用,但是却是这个环境中最常用的。它暴露的bean properties可以用来配置一个
java.util.concurrent.ThreadPoolExecutor
,把它包装到一个
TaskExecutor
中。如果你需要更加先进的类,比如
ScheduledThreadPoolExecutor
,我们建议你使用
ConcurrentTaskExecutor
来替代。

TimerTaskExecutor


这个实现使用一个
TimerTask
作为其背后的实现。它和
SyncTaskExecutor
的不同在于,方法调用是在一个独立的线程中进行的,虽然在那个线程中是同步的。

WorkManagerTaskExecutor


CommonJ 是BEA和IBM联合开发的一套规范。这些规范并非Java EE的标准,但它是BEA和IBM的应用服务器实现的共同标准

这个实现使用了CommonJ WorkManager作为其底层实现,是在Spring context中配置CommonJ WorkManager应用的最重要的类。和
SimpleThreadPoolTaskExecutor
类似,这个类实现了WorkManager接口,因此可以直接作为WorkManager使用。


23.4.3. 使用
TaskExecutor

Spring的
TaskExecutor
实现作为一个简单的JavaBeans使用。在下面的示例中,我们定义一个bean,使用
ThreadPoolTaskExecutor
来异步打印出一系列字符串。
import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {

private class MessagePrinterTask implements Runnable {

private String message;

public MessagePrinterTask(String message) {
this.message = message;
}

public void run() {
System.out.println(message);
}

}

private TaskExecutor taskExecutor;

public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}

public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}


可以看到,无需你自己从池中获取一个线程来执行,你把自己的
Runnable
类加入到队列中去,
TaskExecutor
使用它自己的内置规则来决定何时应该执行任务。

为了配置
TaskExecutor
使用的规则,暴露了简单的bean properties。
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>

<bean id="taskExecutorExample" class="TaskExecutorExample">
<constructor-arg ref="taskExecutor" />
</bean>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: