打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
spring定时任务+线池程实现
之前看了程序员杂志上关于spring 定时任务实现异步任务的文章,自己架了一套帮助实现一些费时的操作。
在实现中发现几个问题
1、定时任务中时间设置是这样的
Java代码 
 
<property name="delay" value="1000" />
<!-- 每次任务间隔 5秒-->
<property name="period" value="5000" />
在某些配置下某任务开始后还没执行完过了5秒,第二个任务又起来了。
这与我的设计冲突。我希望任务是执行完后等5秒再进行第二个任务。
最后发现这个类可以
Java代码 
 
<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秒之后就运行了。我实现的代码是
Java代码 
 
//等待线程执行完毕
while(threadPool.getActiveCount() > 0){
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
其实也可以采用观察者模式让线程池中任务发消息给主任务,主任务等待,
这个我之前有发给文章。 http://guoba6688-sina-com.iteye.com/blog/719972
附上所有代码
Java代码 
 
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"});
}
}
Java代码 
 
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 ");
}
}
Java代码 
 
<?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>
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
图灵学院:java高并发之Executor
新特征-信号量(二十)
Java线程(六):线程池
以实例简介Java中线程池的工作特点
java并发(二十)线程池
C# 线程池ThreadPool用法简介
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服