Spring中的異步任務、線程池、定時器定時任務

1Spring異步任務

 

開啓異步配置(@EnableAsync註解指定或<task:annotation-driven>標籤配置

1、用Java註解:

 

第一步:在類的申明前使用@EnableAsync註解開啓異步調用功能。

第二步:public AsyncTaskExecutor taskExecutor() 方法自定義自己的線程池,線程池前綴”Anno-Executor”。如果不定義,則使用系統默認的線程池。

 

@EnableAsync // 啓動異步調用

public class AsyncApplicationWithAnnotation {

/* 略 */

/**

     * 自定義異步線程池

     * @return

     */

    @Bean

    public AsyncTaskExecutor taskExecutor() { 

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        executor.setThreadNamePrefix("Anno-Executor");

        executor.setMaxPoolSize(10); 

 

        // 設置拒絕策略

        executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {

            @Override

            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

                // .....

            }

        });

        return executor; 

    }

}
  

 

2、用XML配置:

 

第一步:使用<task:executor>標籤定義線程池

第二步:使用<task:annotation-driven>標籤啓動異步線程池配置

如下spring-async.xml配置:

 

    <!-- 等價於 @EnableAsync, executor指定線程池 -->

    <task:annotation-driven executor="xmlExecutor"/>

    <!-- id指定線程池產生線程名稱的前綴 -->

    <task:executor

        id="xmlExecutor"

        pool-size="5-25"

        queue-capacity="100"

        keep-alive="120"

        rejection-policy="CALLER_RUNS"/>
  

 

有關線程池的拒絕策略,參考下文:

線程池--拒絕策略RejectedExecutionHandler

 

編寫異步任務(@Async註解指定)

 

1、編寫普通Java類,並設置方法爲@Async註解

 

  只需要簡單這麼一步即可在執行註解方法時自動由Spring框架執行異步操作。

p

ackage tech.bbwang.springtask.scheduled.demo;

 

import org.springframework.stereotype.Component;

import java.util.Date;

 

@Component

public class ScheduledTaskExample {

    public ScheduledTaskExample(){
    }

    @Async
    public void printTime(){
       System.out.println((new Date()).toString());
    }
}
 

 

2、線程池

 

配置線程池

 

最簡單的形式,只需要在spring配置文件里加一條配置即可。

 

<task:executor id="xmlExecutor" pool-size="2" />

 

 添加此配置需要在Spring配置文件的<beans>頭部添加下面的約束文件(task相關處的命名空間)

 

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 

 

使用線程池

線程池xmlExecutor作爲一個Spring的bean存在,可以被注入到需要的地方。

比如:

 

定義一個使用線程池的類TaskExecutorExample,該類使用線程池跑10個打印當前時間的任務。

 

package tech.bbwang.springtask.demo;

import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;
import tech.bbwang.App;

import java.util.HashMap;
import java.util.Map;

/**

 * 任務執行樣例

 */

@Component

public class TaskExecutorExample

{

   private TaskExecutor taskExecutor;

    public TaskExecutorExample(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    public void printMessages() {

        for(int i = 0; i <10; i++) {
           taskExecutor.execute(new Runnable(){
            public void run(){
            System.out.println((new Date()).toString());
           }

         });
        }
    }

}
 

 

Spring配置文件設置:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <context:component-scan base-package="tech.bbwang.springtask.demo"/>
    <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="tech.bbwang.springtask.demo.TaskExecutorExample">
        <constructor-arg ref="taskExecutor" />
    </bean>
</beans>
 

 

3、定時器和定時任務

 

定義定時器

 

spring配置文件:

 

<!-- pool-size:此參數默認爲1,此時,不同的定時任務不可同時進行,因爲線程數不夠。需要自己設置>1的數值來保證,同一個定時任務前一個未完成情況下不啓動下一個,但不用的定時任務可以同時進行-->
<task:scheduler id="taskScheduler" pool-size="10"/>
 

 

定義定時任務

 

spring配置文件:

 

<task:scheduled-tasks>
        <!-- 配置定時任務,cron=一秒一次-->
        <task:scheduled ref="scheduledTaskExample" method="printTime" cron="0/5 * * * * ?"/>
        <!-- 配置定時任務,cron=每日0時和12時各執行一次任務-->
        <!--Cron表達式生成器 http://www.pdtools.net/tools/becron.jsp-->
        <!--<task:scheduled ref="scheduledTaskExample" method="printTime" cron="0/1 0/1 0,12 * * ?"/>-->
    </task:scheduled-tasks>
 

 

有關corn表達式可以參考:

Cron表達式生成器

cron表達式詳解

 

定義定時任務類

 

 

package tech.bbwang.springtask.scheduled.demo;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
public class ScheduledTaskExample {

    public ScheduledTaskExample(){
    }
     @Async
    public void printTime(){
        System.out.println((new Date()).toString());
    }
}

 

 

 定義運行類

其實已經完全由Spring配置解決了運行問題,只需要給一個運行Spring配置的主函數即可。

 

package tech.bbwang;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.concurrent.CountDownLatch;

public class SpringAsyncTask {

   public static void main( String[] args )
    {
        new ClassPathXmlApplicationContext("spring-async*.xml");
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章