Spring提供的线程池支持

标签: spring 线程池 | 发表时间:2012-07-04 11:10 | 作者:360zhi
出处:http://www.cnblogs.com/

核心提示:一旦企业应用越来越复杂时(比如,基于流程服务器的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,即不启用资源节流。

<bean id="simpleAsyncTaskExecutor"

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

<property name="daemon" value="true" />

<property name=" concurrencyLimit" value="2" />

<property name="threadNamePrefix" value="simpleAsyncTaskExecutor" />

</bean>

在Spring 2.0内部实现中,JMS集成会使用SimpleAsyncTaskExecutor完成JMS消息监听器的注册、执行等工作,我们将在第16章介绍这方面的内容。每次用户提交新的任务给SimpleAsyncTaskExecutor时,它都会启动新的线程来响应客户请求。这意味着,它并没有提供线程池功能。更何况,在Java EE环境中,随便启动新的线程并不是推荐的做法,因为Java EE容器没有办法管理到这些线程。所以,我们要改进SimpleAsyncTaskExecutor。

Java SE 5.0引入了ThreadPoolExecutor、ScheduledThreadPoolExecutor。Spring 2.0借助于ConcurrentTaskExecutor和ThreadPoolTaskExecutor能够通过IoC配置形式自定义它们暴露的各个属性。比如,下面给出ThreadPoolTaskExecutor的使用示例,其暴露的各个属性其实是ThreadPoolExecutor的属性,这体现了DI容器的优势。

<bean id="threadPoolTaskExecutor"

class="org.springframework.scheduling.concurrent. ThreadPoolTaskExecutor">

<property name="corePoolSize" value="2" />

<property name="keepAliveSeconds" value="200" />

<property name="maxPoolSize" value="10" />

<property name="queueCapacity" value="60" />

</bean>

Spring 2.0在集成java.util.Timer任务调度机制过程中,还引入了TimerTaskExecutor。此时,用户提交的所有任务将交由Timer本身的单个线程执行,其示例配置如下。这一单个线程会以串行的方式完成用户提交给它的所有任务。

<bean id="timerTaskExecutor"

class="org.springframework.scheduling.timer. TimerTaskExecutor">

<property name="delay" value="10000" />

</bean>

在集成Quartz任务调度框架过程中,Spring引入了SimpleThreadPoolTaskExecutor。此时,用户提交的所有任务将交由Quartz维护的线程池执行,其示例配置如下。很显然,开发者能够控制这一线程池的具体细节。在使用Quartz实现任务调度过程中,它会使用内置的线程池处理任务。

<bean id="simpleThreadPoolTaskExecutor"

class="org.springframework.scheduling.quartz. SimpleThreadPoolTaskExecutor">

<property name="makeThreadsDaemons" value="true"/>

<property name="threadCount" value="5" />

<property name="threadNamePrefix" value="simpleThreadPoolTaskExecutor"/>

<property name="waitForJobsToCompleteOnShutdown" value="true" />

</bean>

如果开发者在使用BEA WebLogic 9+和IBM WebSphere 6+版本的Java EE应用服务器,则应用通过JNDI树还能够获得CommonJ提供的Java EE容器受管连接池。我们之前使用的TimerTaskExecutor、SimpleThreadPoolTaskExecutor并没有使用到容器受管连接池,而且它们也不能够使用到Java EE应用的上下文信息,而CommonJ却可以做到。甚至,CommonJ同时支持同步和异步处理用户提交的任务。当然,CommonJ并不是Java EE规范的组成部分,因此只有BEA和IBM客户才能够享受到这一待遇,即WorkManagerTaskExecutor。

WorkManagerTaskExecutor的示例配置如下。我们可以在很多场合使用到这一容器受管的线程池服务,比如,当使用Spring JMS集成开发消息应用时,开发者可以在WebSphere或WebLogic中使用WorkManagerTaskExecutor提供的线程池服务。

<bean id="workManagerTaskExecutor"

class="org.springframework.scheduling.commonj. WorkManagerTaskExecutor">

<property name="workManagerName" value="jndi/workManager" />

</bean>

 

本文链接

相关 [spring 线程池] 推荐:

Spring提供的线程池支持

- - 博客园_首页
核心提示:一旦企业应用越来越复杂时(比如,基于流程服务器的EIS),它们对相关技术也提出了更高的要求. 在使用 EJB 3.0组件技术开发企业应用过程中,它们能够享受到EJB容器提供的线程池、任务调度(@Timeout)服务. 现如今,运行于Web容器的Web应用、单独的桌面应用. 一旦企业应用越来越复杂时(比如,基于流程服务器的EIS),它们对相关技术也提出了更高的要求.

如何使用Spring开发和监控线程池服务

- - ImportNew
线程池对执行同步或异步的任务很重要. 本文展示如何利用Spring开发并监控线程池服务. 创建线程池的其他两种方法已讲解过. 第1步:创建Maven工程. (可以使用Maven或IDE的插件创建). 将Spring的依赖添加到Maven的pom.xml文件中. 使用下面的插件创建可执行jar包. 创建一个实现Runnable接口的新TestTask类.

使用SPRING中的线程池ThreadPoolTaskExecutor实现JAVA并发

- - Java - 编程语言 - ITeye博客
//线程池所使用的缓冲队列 . //线程池维护线程的最少数量 . //线程池维护线程的最大数量 . //线程池维护线程所允许的空闲时间 .  .      .      .      .

Java线程池

- - 企业架构 - ITeye博客
线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的. 在jdk1.5之后这一情况有了很大的改观. Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用. 为我们在开发中处理线程的问题提供了非常大的帮助.

Java 线程池

- - 编程语言 - ITeye博客
在项目中,系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互. 在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存周期很短的线程时,更应该考虑使用线程池. 使用线程池可以有效地控制系统中并发线程的数量,当系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过此数.

Spring详解

- - CSDN博客架构设计推荐文章
Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目的是简化企业开发.. PersonDaoBean 是在应用内部创建及维护的. 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.

Spring定时

- - 行业应用 - ITeye博客
spring的定时任务配置分为三个步骤:. . . . . .

简单Spring+hessian

- - Web前端 - ITeye博客
简单的Spring+hessian. dist\modules里面的 spring-webmvc.jar . lib\caucho 里面的hessian-3.1.3.jar. 里面有个接口interface:. 建立一个model层:(实现Serializable接口). 在WEB-INF下面创建一个remoting-servlet.xml:.

Spring MVC 和 Struts2

- - CSDN博客架构设计推荐文章
Web层面的框架学习了三个Struts1和2,SpringMVC,那他们之间肯定存在一个优劣和适用的环境,Struts1和2的异同点我已经做过对比《 Struts1和Struts2》,这篇将对比下Struts2和SpringMVC的异同,下面数据基本来源于网络,本人是搜集整理所得,供大家参考. 一个项目使用什么样的技术,决定的因素很多,我所能想到的有:对系统的性能、开发的效率、团队学习的成本、业务场景等,下面尽量从这几个方面入手,来分析比较下他们之间存在的优劣.

Spring AOP详解

- - Java - 编程语言 - ITeye博客
        最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP来解决. 一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容. 例如,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 1.对部分函数的调用进行日志记录,用于观察特定问题在运行过程中的函数调用情况.