资质升级业绩备案在哪个网站做,专业软件定制开发公司,公众号开发网站建设合同,cms模板一、概述Spring框架分别使用TaskExecutor和TaskScheduler接口提供异步执行和任务调度的抽象。Spring还提供了这些接口的实现#xff0c;这些接口支持线程池或将其委托给应用服务器环境中的CommonJ。二、TaskExecutorSpring 2.0 开始引入的新的抽像。Executors 是线程池的Java …一、概述Spring框架分别使用TaskExecutor和TaskScheduler接口提供异步执行和任务调度的抽象。Spring还提供了这些接口的实现这些接口支持线程池或将其委托给应用服务器环境中的CommonJ。二、TaskExecutorSpring 2.0 开始引入的新的抽像。Executors 是线程池的Java 5名称。之所以称作是“执行器”是因为不能保证底层实现实际上是一个池;执行程序可以是单线程的甚至是同步的。Spring的TaskExecutor接口与java.util.concurrent是等价的。2.1 TaskExecutor类型SimpleAsyncTaskExecutor线程不会重用每次调用开启一个新的线程。支持并发超过最大并发调用数时会阻塞直到释放一个槽为止。SyncTaskExecutor不会异步执行调用。每次调用都发生在调用线程中。它主要用于不需要多线程的情况。ConcurrentTaskExecutorJava 5 Java .util.concurrent. executor的包装。替代方案是ThreadPoolTaskExecutor它将Executor配置参数作为bean属性公开。很少使用。SimpleThreadPoolTaskExecutorQuartz的SimpleThreadPool的一个子类它监听Spring的生命周期回调。Quartz组件和非Quartz组件共享需要共享一个线程池时通常会使用这种方法。ThreadPoolTaskExecutor只能在java5中使用。公开了用于配置java.util.concurrent的bean属性。如果需要高级的东西比如ScheduledThreadPoolExecutor建议使用ConcurrentTaskExecutor替代。TimerTaskExecutor通过TimerTask支撑实现。 不同于SyncTaskExecutor因为方法调用在一个单独的线程中执行尽管它们在那个线程中是同步的。WorkManagerTaskExecutor使用CommonJ WorkManager作为它的支持实现并且是在Spring上下文中设置CommonJ WorkManager引用的中心便利类。与SimpleThreadPoolTaskExecutor类似这个类实现了WorkManager接口因此也可以直接作为WorkManager使用。2.2 使用 TaskExecutorpublic 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将使用的规则三、TaskScheduler除了任务执行者抽象之外。Spring 3.0还引入了一个TaskScheduler它有多种方法来调度未来某个时候运行的任务。public interface TaskScheduler { ScheduledFuture schedule(Runnable task, Trigger trigger); ScheduledFuture schedule(Runnable task, Date startTime); ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); ScheduledFuture scheduleAtFixedRate(Runnable task, long period); ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);}名为“schedule”的方法它只接受可运行的日期。这将导致任务在指定时间后运行一次。所有其他方法都能够安排任务重复运行。固定速率和固定延迟方法用于简单的、周期性的执行但是使用 Trigger 的方法要灵活得多。3.1 Trigger触发器的基本思想是执行时间可以根据过去的执行结果甚至任意条件来确定。如果这些决定确实考虑了前面执行的结果那么该信息在TriggerContext中是可用的。public interface Trigger { Date nextExecutionTime(TriggerContext triggerContext);}public interface TriggerContext { Date lastScheduledExecutionTime(); Date lastActualExecutionTime(); Date lastCompletionTime();}TriggerContext是最重要的部分。它封装了所有相关的数据如果有必要将来还可以进行扩展。TriggerContext是一个接口(默认情况下使用SimpleTriggerContext实现)。3.2 Trigger 实现Spring提供了触发器接口的两个实现。最有趣的是CronTrigger。它支持基于cron表达式的任务调度。scheduler.schedule(task, new CronTrigger(* 15 9-17 * * MON-FRI));另一个开箱即用的实现是一个周期性Trigger 它接受一个固定的周期、一个可选的初始延迟值以及一个布尔值用来指示周期应该解释为固定速率还是固定延迟。由于TaskScheduler接口已经定义了以固定速率或固定延迟调度任务的方法因此应该尽可能直接使用这些方法。PeriodicTrigger实现的价值在于它可以在依赖于触发器抽象的组件中使用。例如允许周期性Trigger 、基于cro的Trigger 甚至自定义Trigger 实现可以互换使用这可能很方便。这样的组件可以利用依赖注入这样就可以在外部配置这样的Trigger 。3.3 TaskScheduler实现在应用服务器环境中TaskScheduler提供的灵活性尤其重要。因为在这种环境中线程不应该由应用程序本身直接创建。对于这种情况Spring提供了一个TimerManagerTaskScheduler它将委托给CommonJ TimerManager实例通常配置为JNDI-lookup。四、调度和异步执行的注解支持4.1 开启scheduling 注解功能为了支持Scheduled和Async注释请将EnableScheduling和EnableAsync添加到Configuration类中ConfigurationEnableAsyncEnableSChedulingpublic class AppConfig {}你可以自由选择应用程序的相关注释。例如如果只需要支持Scheduled那么只需省略EnableAsync即可。对于更细粒度的控制可以另外实现调度器和/或AsyncConfigurer接口。如果你更喜欢xml配置这样配置。}4.2 ScheduledScheduled添加到方法上//上一次调用完之后五秒再调用一次,依此循环下去Scheduled(fixedDelay5000)public void doSomething() { // something that should execute periodically}//连续的每次调用开始时间之间间隔5sScheduled(fixedRate5000)public void doSomething() { // something that should execute periodically}//Scheduled(cron*/5 * * * * MON-FRI)public void doSomething() { // something that should execute on weekdays only}值得注意的是调度的方法返回值必须是void并且不能期望有任何参数。如果方法需要与来自应用程序上下文的其他对象交互那么这些对象通常是通过依赖注入提供的。4.3 Async注解添加了Async注解的方法会异步执行。换句话说方法调用后会立即返回方法的实际执行将发生在提交给Spring TaskExecutor的任务中。Asyncvoid doSomething() { // this will be executed asynchronously}/Scheduled注释的方法不同这些方法可以预期参数.//因为调用方将在运行时以“正常”方式调用它们而不是从容器管理的调度任务中调用。Asyncvoid doSomething(String s) { // this will be executed asynchronously}// 具有Future回调返回值//执行其它任务的优先级 依然是高于执行回调的优先级。AsyncFuture returnSomething(int i) { // this will be executed asynchronously}4.4 指定Async注解的执行器默认情况下在方法上指定Async时将使用的执行器是提供“annotation-driven”元素的执行器如上所述。然而当需要指示在执行给定方法时应该使用非默认的执行器时可以使用Async注释的值属性。Async(otherExecutor)void doSomething(String s) { // this will be executed asynchronously by otherExecutor}五、Task 命名空间从Spring 3.0开始有一个用于配置TaskExecutor和TaskScheduler实例的XML名称空间。并提供了一种方便的方法可以将任务配置为使用触发器进行调度。5.1 scheduler 元素id属性用作线程池中线程的前缀名。如果不指定pool-size默认的线程池中只有一个线程。5.2 executor元素与上面的调度器一样为’id’属性提供的值将用作池中线程名称的前缀。就池大小而言executor’元素比’scheduler’元素支持更多的配置选项。首先ThreadPoolTaskExecutor的线程池本身是可配置的。执行程序的线程池可能对核心和最大大小有不同的值而不仅仅是单个大小。如果提供了单个值那么执行器将拥有一个固定大小的线程池(核心和最大大小相同)。然而“executor”元素的“池大小”属性也接受“min-max”形式的范围。5.3 scheduled-tasks元素Spring task namespace 最强大的特性是支持在Spring应用程序上下文中配置要调度的任务。这与Spring中的其他“方法调用者”类似例如JMS名称空间提供的配置消息驱动pojo的方法。六、Quartz SchedulerQuartz使用触发器、作业和作业细节对象来实现各种作业的调度。有关Quartz背后的基本概念请参阅http://quartz-scheduling er.org。为了方便起见Spring提供了两个类它们简化了基于Spring的应用程序中Quartz的使用。6.1 使用JobDetailBeanJobDetail对象包含运行作业所需的所有信息。Spring框架提供了JobDetailBean它使JobDetail更接近于具有合理默认值的实际JavaBean。job detail bean 具有运行作业(ExampleJob)所需的所有信息。timeout在job data map指定。job data map可以通过JobExecutionContext(在执行时传递给您)获得但是JobDetailBean还将 job data map 中的属性映射到实际job的属性。因此在本例中如果ExampleJob包含一个名为timeout的属性JobDetailBean将自动应用它。package example;public class ExampleJob extends QuartzJobBean { private int timeout; /*** Setter called after the ExampleJob is instantiated* with the value from the JobDetailBean (5)*/ public void setTimeout(int timeout) { this.timeout timeout; } protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { // do the actual work }}6.2 使用MethodInvokingJobDetailFactoryBean使用MethodInvokingJobDetailFactoryBean你可以调用特定对象上的方法。使用上面的配置将会导致ExampleBusinessObject .doIt()方法被调用。public class ExampleBusinessObject { // properties and collaborators public void doIt() { // do the actual work }}使用MethodInvokingJobDetailFactoryBean不再需要创建只调用一个方法的一行作业只需要创建实际的业务对象并连接到它。默认情况下Quartz作业是无状态的导致作业相互干扰的可能性。如果为相同的JobDetail指定两个触发器那么可能在第一个作业完成之前第二个作业就会开始。如果JobDetail类实现有状态接口则不会发生这种情况。在第一项工作完成之前第二项工作不会开始。要使方法调用jobdetailfactorybean产生的作业非并发请将并发标志设置为false。6.3 作业调度尽管我们能使用MethodInvokingJobDetailFactoryBean调用特定对象上的方法但是我们还是需要调度作业 。这需要使用触发器和scheduler erfactorybean完成。Quartz 提供了多种触发器Spring提供了两种Quartz 工厂对象CronTriggerFactoryBeanSimpleTriggerFactoryBean两种触发器的示例关于SchedulerFactoryBean的等多属性设置 参考SchedulerFactoryBean javadocJava架构师丨苏先生专注于Java开发技术的研究与知识分享————END————点赞(感谢)...转发(感谢)...关注(感谢)...推荐阅读Java程序员备战“金九银十”必备的面试技巧(附携程Java岗面试题)字节跳动Java研发面试99题(含答案)JVMSpringMySQL线程池锁......