Task Execution and Scheduling

Using a TaskExecutor

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);
        }

    }

    //spring 經過xml 注入的taskExecutor對象
    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));
        }
    }

}

//xml配置
<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>

corePoolSize: 線程池維護線程的最少數量java

keepAliveSeconds  線程池維護線程所容許的空閒時間spring

maxPoolSize   線程池維護線程的最大數量express

queueCapacity 線程池所使用的緩衝隊列ide

當一個任務經過execute(Runnable)方法欲添加到線程池時:this

若是此時線程池中的數量小於corePoolSize,即便線程池中的線程都處於空閒狀態,也要建立新的線程來處理被添加的任務。線程

若是此時線程池中的數量等於 corePoolSize,可是緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列。code

若是此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,而且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。xml

若是此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,而且線程池中的數量等於maximumPoolSize,那麼經過 handler所指定的策略來處理此任務。對象

            也就是:處理任務的優先級爲:核心線程corePoolSize、任務隊列workQueue、最大線程 maximumPoolSize,若是三者都滿了,使用handler處理被拒絕的任務。隊列

當線程池中的線程數量大於 corePoolSize時,若是某線程空閒時間超過keepAliveTime,線程將被終止。這樣,線程池能夠動態的調整池中的線程數。


Enable scheduling annotations

想要spring執行@Scheduled註解要在配置文件中進行開啓,@Scheduled 支持使用SpringEL表達式,這樣若是咱們在properties中配置好Cron值,而後注入。

@Configuration
@EnableScheduling
public class AppConfig {
}

//任務
@Component
public class TestJob {

    @Scheduled(cron = "1 * * * * ?")
    public void testJob(){
        System.out.println("任務1");
        System.out.println(new Date().toLocaleString());
    }
}

若是使用xml咱們能夠這麼寫

<task:annotation-driven>

The @Scheduled Annotation

/**
 * The @Scheduled annotation can be added to a method along with trigger metadata. For example,
 * the following method would be invoked every 5 seconds with a fixed delay, 
 * meaning that the period will be measured from the completion time of each preceding invocation.
 */
@Scheduled(fixedDelay=5000)
public void doSomething() {
        // something that should execute periodically
 }
/**
*  If a fixed rate execution is desired, 
*  simply change the property name specified within the annotation.
*  The following would be executed every 5 seconds measured between the successive start times of each invocation.
*/
@Scheduled(fixedRate=5000)
public void doSomething() {
        // something that should execute periodically
}
/**
*  For fixed-delay and fixed-rate tasks, 
*  an initial delay may be specified indicating the number of milliseconds to wait before the first execution of the method.
*/
@Scheduled(initialDelay=1000, fixedRate=5000)
public void doSomething() {
        // something that should execute periodically
 }
/**
 * If simple periodic scheduling is not expressive enough, 
 * then a cron expression may be provided. For example, 
 * the following will only execute on weekdays.
 */
@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
        // something that should execute on weekdays only
 }

 Using the Quartz Scheduler

<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="example.ExampleJob" />
    <property name="jobDataAsMap">
        <map>
            <entry key="timeout" value="5" />
        </map>
    </property>
</bean>

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
    }

}

Using the MethodInvokingJobDetailFactoryBean

<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="exampleBusinessObject" />
    <property name="targetMethod" value="doIt" />
    
</bean>

<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>

public class ExampleBusinessObject {    
// properties and collaborators

    public void doIt() {      
      // do the actual work
    }
}

上面是任務實體,咱們還須要觸發器,下面是兩種觸發器

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
    <!-- see the example of method invoking job above -->
    <property name="jobDetail" ref="jobDetail" />
    <!-- 10 seconds -->
    <property name="startDelay" value="10000" />
    <!-- repeat every 50 seconds -->
    <property name="repeatInterval" value="50000" />
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="exampleJob" />
    <!-- run every morning at 6 AM -->
    <property name="cronExpression" value="0 0 6 * * ?" />
</bean>

要讓定時任務容許咱們還須要配置SchedulerFactoryBean

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="cronTrigger" />
            <ref bean="simpleTrigger" />
        </list>
    </property>
</bean>
相關文章
相關標籤/搜索