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

spring定时任务+线池程实现

阅读更多

之前看了程序员杂志上关于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.iteye.com/blog/719972

 

附上所有代码

 

 

package com.my.task;

import java.util.TimerTask;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * 
 * 主任务起动
 *
 * @author 锅巴
 * @version 1.0 2010-7-29
 */
public class MainExecutor extends TimerTask {

    private ThreadPoolTaskExecutor threadPool;
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        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() {
        // TODO Auto-generated method stub
    
        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>

 

4
0
分享到:
评论
1 楼 supben 2010-11-17  
ScheduledExecutorTask
能配置任务开始的固定时分秒么。
类似quartz那种。

相关推荐

Global site tag (gtag.js) - Google Analytics