其他分享
首页 > 其他分享> > CCCC

CCCC

作者:互联网

Spring Framework分别通过TaskExecutor和TaskScheduler两个接口提供了异步执行任务和定时任务的功能。Spring还实现了这两个接口支持线程池和委派给CommonJ在服务器环境下。最终,这些实现区分了Java SE 5、Java SE 6和Java EE环境。
Spring还整合支持Timer和Quartz Scheduler。你可以通过使用FactoryBean来分别的实例化Timer和Trigger实例。而且,还有一个简便的类用于Quartz Scheduler和Timer让你在一个存在的的对象中异步调用方法。(类似于MethodInvokingFactoryBean的操作)

Spring TaskExecutor 抽象

执行是JDK为线程池的概念,名称“executor”事实上无法保证实际工作的是线程池。一个“executor”可能是单线程也可能是同步的,Spring的抽象层隐藏了在Java SE和Java EE环境下实现的不同。
Spring的TaskExecutor跟java.util.concurrent.Executor接口是雷同的。事实上,当在Java5中使用线程池的时候,需要抽象出来,是它存在的主要原因。接口中仅仅包含了一个execute方法用来接口基于语法和配置的线程池。
TaskExecutor为其他Spring组件抽象出来的线程池需要的地方使用。比如ApplicationEventMulticaster和JMS的AbstractMessageListenerContainer和Quart整合的TaskExecutor抽象线程池。但是,如果你的类需要线程池功能,你依然可以为你自己使用这个抽象层


TaskExecutor 类型

Spring包含了一些实现TaskExecutor前置类,在所有的情况,你应该是不要自己来实现这些接口的,下面是Spring提供的几种类型:


使用一个TaskExecutor

Spring的TaskExecutor实现作为一个简单的Java类使用,在下面的实例中,我们定义了一个使用了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));
        }
    }
}

正如你所看到的,你添加了线程到队列中,而不是从线程池中接口一个线程,然后自行执行。TaskExecutor使用内部规则来决定任何合适被执行。
配置TaskExecutor的使用规则,如下我们展示了简单的类属性配置:

<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>

Spring TaskScheduler抽象层

除了TaskExecutor抽象层,Spring 3.0引用了TaskScheduler类,它携带了大量的方法,可以设置在未来的某个时间点运行。下面列表展示了TaskScheduler接口定义:


public interface TaskScheduler {

    ScheduledFuture schedule(Runnable task, Trigger trigger);

    ScheduledFuture schedule(Runnable task, Instant startTime);

    ScheduledFuture schedule(Runnable task, Date startTime);

    ScheduledFuture scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);

    ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);

    ScheduledFuture scheduleAtFixedRate(Runnable task, Duration period);

    ScheduledFuture scheduleAtFixedRate(Runnable task, long period);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, Duration delay);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}

其中最简单的方式是一个名为shcedule的方法,它仅仅只需要一个线程和一个时间。这种会在时间到的之后,执行一次任务。其他所有的方法都是可以进行重复任务协作的。固定的周期和延时用于简单的周期执行,但是接受触发器的方式更为灵活。

Trigger接口

Trigger接口实际上是受JSR-236的启发,在Spring3.0中还未正式的被实现。使用Trigger的基本方法是执行次数受限于过去的执行结果或者任意条件。如果确实考虑了前面的执行结果,那么这些信息在TriggerContext中就可以使用。Trigger的接口非常简单,如下列表所示:

public interface Trigger {

    Date nextExecutionTime(TriggerContext triggerContext);
}

TriggerContext是最重要的部分,它包含了所有的相关数据,如果有需要还可以对它进行扩展。TriggerContext是一个接口,SimpleTriggerContext被作为默认的实现。下面列出了Trigger实现的相关可用方法:

public interface TriggerContext {

    Date lastScheduledExecutionTime();

    Date lastActualExecutionTime();

    Date lastCompletionTime();
}
Trigger实现

Spring提供了Trigger接口的两个实现。最有趣的是CronTrigger类,它允许任务安全基于闹钟表达式。举个例子,下列任务呗安排在工作日上午9点到5点,每个小时后的15分钟后执行。

scheduler.schedule(task, new CronTrigger("0 15 9-17 * * MON-FRI"));

另一个实现是PeriodicTrigger,它接收固定周期、一个初始化的延迟时间和一个布尔值来确定执行周期被解读为固定率还是固定延时。因为TaskScheduler接口已经为固定比例和固定延时来分配任务,这些方法我们应该尽可能的直接调用。PerioddicTrigger实现可以基于Trigger抽象层来使用。比如,在使用周期出发、基于时钟出发和自定义出发实现上达到互换的能力是很方便的。这样的组件可以非常方便的配置和使用。

TaskScheduler实现

作为Spring中的TaskExecutor抽象层,首要的好处是TaskScheduler任务安排和开发应用环境解耦。当部署的应用服务器,线程不由应用本身直接创建的时候,这个抽象层显得额外的重要。在这种场景,Spring提供了TimerManagerTaskScheduler整合CommonJ的TimerManager在WebLogic和WebSphere上也是可以的

标签:Runnable,Spring,Trigger,CCCC,task,线程,TaskExecutor
来源: https://www.cnblogs.com/deky97/p/10974952.html