`
bbwang8088
  • 浏览: 43952 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics