之前看了程序员杂志上关于spring 定时任务实现异步任务的文章,自己架了一套帮助实现一些费时的操作。 在实现中发现几个问题 1、定时任务中时间设置是这样的 - <property name="delay" value="1000" />
- <!-- 每次任务间隔 5秒-->
- <property name="period" value="5000" />
在某些配置下某任务开始后还没执行完过了5秒,第二个任务又起来了。 这与我的设计冲突。我希望任务是执行完后等5秒再进行第二个任务。 最后发现这个类可以 - <bean id="springScheduleExecutorTask"
- class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
- <!-- 配置主任务 -->
- <property name="runnable" ref="mainExecutor" />
- <!-- 程序启动后延迟1秒执行第一次任务 -->
- <property name="delay" value="1000" />
- <!-- 每次任务间隔 5秒-->
- <property name="period" value="5000" />
- </bean>
2、在主任务中我把小任务分放给线程池操作,必须要等线程池完成工作后才能结束主任务run 如果起动线程池主任务run完毕,第二个任务5秒之后就运行了。我实现的代码是 -
- while(threadPool.getActiveCount() > 0){
- try{
- Thread.sleep(1000);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
其实也可以采用观察者模式让线程池中任务发消息给主任务,主任务等待, 这个我之前有发给文章。 http://guoba6688-sina-com./blog/719972 附上所有代码 - package com.my.task;
-
- import java.util.TimerTask;
-
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-
-
-
-
-
-
-
- public class MainExecutor extends TimerTask {
-
- private ThreadPoolTaskExecutor threadPool;
-
- @Override
- public void run() {
-
- System.out.println("MainExecutor is start");
- try{
- Thread.sleep(5000);
- }catch(Exception e){
- e.printStackTrace();
- }
- threadPool.execute(new MyTask(10));
- threadPool.execute(new MyTask(10));
- threadPool.execute(new MyTask(10));
-
-
- while(threadPool.getActiveCount() > 0){
- try{
- Thread.sleep(1000);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
-
- System.out.println("MainExecutor is end");
-
- }
-
- public ThreadPoolTaskExecutor getThreadPool() {
- return threadPool;
- }
-
- public void setThreadPool(ThreadPoolTaskExecutor threadPool) {
- this.threadPool = threadPool;
- }
-
- public static void main(String[] args) {
- new ClassPathXmlApplicationContext(new String[]{"task.context.xml"});
- }
-
- }
- package com.my.task;
-
- public class MyTask implements Runnable{
-
- private int count;
-
- public MyTask(int count){
- this.count = count;
- }
-
- @Override
- public void run() {
-
-
- for(int i=0; i<count; i++){
- System.out.println(Thread.currentThread().getName() + " : " + i);
- }
- System.out.println(Thread.currentThread().getName() + " end ");
-
- }
-
- }
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "/spring-beans.dtd">
- <beans default-autowire="byName">
-
-
-
- <bean id="springScheduledExecutorFactoryBean"
- class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
- <property name="scheduledExecutorTasks">
- <list>
- <ref bean="springScheduleExecutorTask" />
- </list>
- </property>
- </bean>
-
-
- <bean id="springScheduleExecutorTask"
- class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
-
- <property name="runnable" ref="mainExecutor" />
-
- <property name="delay" value="1000" />
- <!-- 每次任务间隔 5秒-->
- <property name="period" value="5000" />
- </bean>
-
- <!-- 主任务 负责扫描任务 将任务分配给线程完成 -->
- <bean id="mainExecutor"
- class="com.my.task.MainExecutor">
- <property name="threadPool" ref="threadPool" />
- </bean>
-
- <!-- 异步线程池 -->
- <bean id="threadPool"
- class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
- <!-- 核心线程数 -->
- <property name="corePoolSize" value="10" />
- <!-- 最大线程数 -->
- <property name="maxPoolSize" value="50" />
- <!-- 队列最大长度 >=mainExecutor.maxSize -->
- <property name="queueCapacity" value="1000" />
- <!-- 线程池维护线程所允许的空闲时间 -->
- <property name="keepAliveSeconds" value="300" />
- <!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
- <property name="rejectedExecutionHandler">
- <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
- </property>
- </bean>
-
- </beans>
|