Spring提供的线程池支持

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

核心提示:一旦企业应用越来越复杂时(比如,基于流程服务器的EIS),它们对相关技术也提出

了更高的要求。在使用EJB 3.0组件技术开发企业应用过程中,它们能够享受到EJB容器提供的线

程池、任务调度(@Timeout)服务。现如今,运行于Web容器的Web应用、单独的桌面应用

一旦企业应用越来越复杂时(比如,基于流程服务器的EIS),它们对相关技术也提出了更高的要求。在使用EJB 3.0组件技术开发企业应用过程中,它们能够享受到EJB容器提供的线程池、任务调度(@Timeout)服务。现如今,运行于Web容器的Web应用、单独的桌面应用也复杂到需要依赖于线程池、任务调度的这类服务,是时候实现贵族到平民的转变了。

过去,很多企业项目可能会自身实现这类底层的非功能性的服务。从Java SE 5.0开始,线程池服务(即,java.util.concurrent包)已经内置到JDK中。至于任务调度服务,其实,自从Java 2 SDK 1.3以来,Java 2就内置了用于任务调度的定时器(比如,java.util.Timer、javax.swing.Timer)。开源领域的Quartz Scheduler正是能够提供企业级任务调度服务的使能技术,而且EJB 2.x也加强了任务调度的支持。甚至,BEA同IBM合作开发了Timer and Work Manager for Application Servers技术规范(CommonJ),这是专门用来解决Java EE应用中的线程池、任务调度问题的。另外,JMX规范中也定义了javax.management.timer.TimerMBean,开发者借助于它能够实现定时JMX通知。

针对上述各种线程池、任务调度支持,Spring 2.0提供了统一的客户视图、抽象,这使得应用根本不用理会底层的具体实现和机制。本章将从分析Spring 2.0提供的线程池支持入手,并过渡到Spring 2.0对任务调度提供的支持当中,从而进入到下一章内容。

15.1 Spring提供的线程池支持

自从Spring 2.0开始,TaskExecutor接口被引入到Spring平台中,这主要受到Java SE 5.0中java.util.concurrent.Executor的影响。这一接口为各种线程池服务提供了抽象,它在统一客户视图

方面起到了最重要的作用。无论是Spring 2.0内部实现中,还是各种基于Spring的企业应用,TaskExecutor的应用随处可见,其定义如下。

public interface TaskExecutor {

//异步或同步执行用户提交的任务

void execute(Runnable task);

}

开发者可以通过execute(Runnable task)方法将待执行的任务提交给TaskExecutor。依据不同的TaskExecutor接口实现,这一任务会以异步或同步的方式进行。如果是同步,则调用者一直处于阻

塞状态,直到任务被执行完成。此时,调用者同目标任务的执行处于同一线程中,因此线程上下

文信息能够传播到目标任务的执行过程中。如果是异步,则一旦提交完任务,调用者即可返回,

并继续进行自身的其他操作。此时,调用者同目标任务的执行位于不同的线程中,因此线程上下

文信息很可能不能够在它们之间共享。应用要合理选择同步或异步。比如,在调用execute()期间,

如果采用Spring受管事务或Acegi提供的企业级安全性服务,则一旦同步或异步选用不当,事务

的ACID属性将得不到保证,而且应用的安全性也得不到保障。

Spring 2.0内置的TaskExecutor接口实现见图15-1,图中除了SyncTaskExecutor外,其他实现都是采用异步方式执行提交的任务的。

图15-1 TaskExecutor继承链

开发者是否还记得,第5章介绍的SimpleApplicationEventMulticaster,它使用了SyncTaskExecutor

辅助完成事件的消费工作,其代码摘录如下。

public class SyncTaskExecutor implements TaskExecutor, Serializable {

//同步调用客户提交的任务

public void execute(Runnable task) {

Assert.notNull(task, "Runnable must not be null");

task.run();

}

}

SyncTaskExecutor的使用非常简单,下面给出了示例,摘自Eclipse taskexecutordemo项目。

TaskExecutor te = new SyncTaskExecutor();

te.execute(new LogRunner());

由于SyncTaskExecutor不存在任何属性,因此它的使用最简单。在使用这一实现的过程中,并不会处触发新线程的创建工作,因为提交的任务同调用者同处于一个线程中。相比之下,异步执行用户任务的SimpleAsyncTaskExecutor的使用复杂些,下面给出了示例代码。此时,它会启动新的Thread,并允许开发者控制并发线程的上限(concurrencyLimit),从而起到一定的资源节流作用。默认时,concurrencyLimit取值为–1,即不启用资源节流。

class="org.springframework.core.task.SimpleAsyncTaskExecutor">

相关文档
最新文档