JAVA操作定时任务

时间:2022-07-16 07:50:24
首先,有一个XML里面,存放若干组以下内容:
1.定时任务执行的时间(或是周期或者某一时间);
2.数据库连接URL\用户名\密码
3.执行的SQL
需要按照指定的时间,在相映的数据库空中执行相映的SQL,当然这个简单.
问题是XML中的内容会被修改、删除、添加的!
如何保证在对XML修改、删除、添加后保证定时任务是按照更新后的XML中的信息执行的?
比如XML中有2组定时任务A组和B组。。。程序已经开始执行。这时我对B组的运行周期或SQL
修改的时候不影响A组的运行情况。。。并且最终B组是按照修改后的信息执行的!
请各位高手指点!急,急,急!

17 个解决方案

#1


这个配置文件加载就需要定时加载,定时检测,意思就是说,可以定时检查你的文件是否有变动,一旦有变动立刻重新加载配置文件,就可以实现你的要求。不外乎多一个线程来检测配置文件修改情况。

#2


quatz,研究下,半天差不多能搞定,
也可能一天以上

#3


比如A任务执行周期为10分钟,当程序运行了5分钟时,B任务被更新了,或又添加了一个C任务!
我并不知道XML中会有几个任务,应为他是可变的!所以我需要循环出来全部任务,并按照指定时间执行!
如何实现A任务在第10分钟可以被执行而不是被重新加载?

#4


这个你可以对这些关键项进行比较啊,其实也很简单,即使是重新加载也没有关系,如果你的A任务没有修改,重新加载之后你比较一下关键是否更改,没有更改你就不用更改A任务的运行环境,所以不会有影响。比如:
  A在运行10分钟后,重新加载了配置文件,这时对其中的关键配置信息进行比较,发现A任务配置并没有改变,那么就忽略,这样A任务就不会受影响。因为你是所有的东西都放在一个配置文件里面,所以一旦配置文件更改你也不知道是哪个任务更改了,所以比较这一步是难免的。只是在于你是否忽略忽略没有更改的任务配置,还是另外重新开始这个任务而已。

#5


TOMCAT一启动就开始执行
public void run() {
Timer time = new Timer();
FabuAttempet aa=new FabuAttempet();
List list =aa.getData();//获得所有任务
for (int i = 0; i < list.size(); i++) {
HashMap map = (HashMap) list.get(i);//每个任务里面的数据
FabuAttempetTask fabuTask = new FabuAttempetTask(map);
time.scheduleAtFixedRate(fabuTask, fabuTask.getFirstTime(), fabuTask
.getCycleTime());
}
}
map里存了以下内容
1.定时任务执行的时间(或是周期或者某一时间);
2.数据库连接URL\用户名\密码 
3.执行的SQL 
等等!
应该如何比较呢。。。比较出不同后应该如何更改或添加新的任务呢?我菜!

#6


许多应用会动态读取配置文件的。另外一些可能会引起应用重新启动(reload)

#7


任务运行的时候加载一次配置文件就行了,至于任务的定时运行,简单的用TimerTask就可以了,复杂点的用Quartz

#8


任务运行的时候加载一次配置文件就行了,至于任务的定时运行,简单的用TimerTask就可以了,复杂点的用Quartz

#9


quatz中这种情况好象叫"有状态的作业",真不知道如何实现啊!
麻烦有经验的高手给个例子,感激不尽!

#10


引用 2 楼 laorer 的回复:
quatz,研究下,半天差不多能搞定,
也可能一天以上


赞成!

#11


那里有quartz比较好的实例!学习他开始从实例(带注释)比较好把!

#12


写了两个类.版主要是有耐心,就看一看,完善一下,应该可以用

package houlei.mission;

import java.io.Serializable;

/**
 * 该类是每个任务的封装Bean类.成员变量,应该是每个任务执行条件.<br>
 * 每个任务都应该有它的唯一标识符id,或者名字name也可以.其他的成员变量(像任务时间之类的),版主自己填写就可以了<br>
 * @author 侯磊
 */
public class Mission implements Serializable{

private static final long serialVersionUID = 1L;
private String id;
private String SQL;

public Mission(String id, String sql) {
this.id = id;
SQL = sql;
}
public boolean canExcute(){
//这里添加任务可以执行的条件.一般是根据成员变量的内容,以及当前时间来决定返回值.
return true;
}
public String getSQL() {
return SQL;
}

public String getId() {
return id;
}

}

#13



package houlei.mission;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 任务管理器的封装类型
 * @author 侯磊
 */
public class MissionManager {
private Map missions = Collections.synchronizedMap(new HashMap());
private File config;
private CheckThread checker;
public MissionManager(File config){
this.config=config;
checker= new CheckThread();
}
private void loadConfigFile(File config){

//这里添加读取配置文件的代码.创建Mission对象
//调用addMission方法更新missions的内容.
//调用removeMission将配置文件中不存在的任务删除.
}
public void addMission(String id,Mission mission){
//missions的Key存放Mission的id(字符串类型);Value存放Mission对象.
missions.put(id,mission);
}
public void removeMission(String id){
missions.remove(id);
}
public void startup(){
checker.start();
}
public void shutdown(){
checker.stop();
}
/**
 * 任务的执行器线程.用于执行任务.
 * @author 侯磊
 */
private class ExcutorThread implements Runnable{
private Mission mission;
private Thread instance;
private boolean running=false;
public ExcutorThread(Mission mission) {
this.mission = mission;
}

public void run() {
//这里添加任务的执行代码.如果有循环结构,要注意条件中添加running变量
mission.getSQL();//...
}
public void start(){
if(running)return;
running=true;
instance = new Thread(this);
instance.start();
}
public void stop(){
if(running){
running=false;
instance.interrupt();
// instance.join();
}
}
}

/**
 * 任务管理器的巡查线程.<br>
 * 用于检测配置文件是否变动,以及任务是否可以执行.
 * @author 侯磊
 */
private class CheckThread implements Runnable{
private long lastReadTime=0L;
private Thread instance = new Thread(this);
private boolean running=false;
public void run() {
while(running){
//检查配置文件的时间.
File file = new File(config.getAbsolutePath());
if(file.lastModified()>lastReadTime){
loadConfigFile(file);
lastReadTime=file.lastModified();
}
//检查任务是否可以执行
synchronized (missions) {
for(Iterator itr = missions.keySet().iterator();itr.hasNext()&&running;){
String id = itr.next().toString();
Mission mission = (Mission)missions.get(id);
if(mission.canExcute()){
new ExcutorThread(mission).start();
}
}
}
try {
Thread.sleep(1000);//巡查间隔
} catch (InterruptedException e) { }
}
}
public void start(){
if(running)return;
running=true;
instance.start();
}
public void stop(){
if(running){
running=false;
instance.interrupt();
// instance.join();
}
}
}
}

#14


感激先尝试下...!

#15


Timer time = new Timer(); 
FabuAttempet aa=new FabuAttempet(); 
List list =aa.getData();//获得所有任务 
for (int i = 0; i < list.size(); i++) { 
HashMap map = (HashMap) list.get(i);//每个任务里面的数据 
FabuAttempetTask fabuTask = new FabuAttempetTask(map); 
time.scheduleAtFixedRate(fabuTask, fabuTask.getFirstTime(), fabuTask 
.getCycleTime()); 


以上是要执行的所有任务,每个任务都需要1个Task所以要循环!我应该加到那里呢?

#16


学到东西了,好帖,先楼主了,收藏了,

#17


楼主截止到2008-06-17 15:50:24的汇总数据:
发帖数:1
结贴数:0
结贴率: 0.00%

#1


这个配置文件加载就需要定时加载,定时检测,意思就是说,可以定时检查你的文件是否有变动,一旦有变动立刻重新加载配置文件,就可以实现你的要求。不外乎多一个线程来检测配置文件修改情况。

#2


quatz,研究下,半天差不多能搞定,
也可能一天以上

#3


比如A任务执行周期为10分钟,当程序运行了5分钟时,B任务被更新了,或又添加了一个C任务!
我并不知道XML中会有几个任务,应为他是可变的!所以我需要循环出来全部任务,并按照指定时间执行!
如何实现A任务在第10分钟可以被执行而不是被重新加载?

#4


这个你可以对这些关键项进行比较啊,其实也很简单,即使是重新加载也没有关系,如果你的A任务没有修改,重新加载之后你比较一下关键是否更改,没有更改你就不用更改A任务的运行环境,所以不会有影响。比如:
  A在运行10分钟后,重新加载了配置文件,这时对其中的关键配置信息进行比较,发现A任务配置并没有改变,那么就忽略,这样A任务就不会受影响。因为你是所有的东西都放在一个配置文件里面,所以一旦配置文件更改你也不知道是哪个任务更改了,所以比较这一步是难免的。只是在于你是否忽略忽略没有更改的任务配置,还是另外重新开始这个任务而已。

#5


TOMCAT一启动就开始执行
public void run() {
Timer time = new Timer();
FabuAttempet aa=new FabuAttempet();
List list =aa.getData();//获得所有任务
for (int i = 0; i < list.size(); i++) {
HashMap map = (HashMap) list.get(i);//每个任务里面的数据
FabuAttempetTask fabuTask = new FabuAttempetTask(map);
time.scheduleAtFixedRate(fabuTask, fabuTask.getFirstTime(), fabuTask
.getCycleTime());
}
}
map里存了以下内容
1.定时任务执行的时间(或是周期或者某一时间);
2.数据库连接URL\用户名\密码 
3.执行的SQL 
等等!
应该如何比较呢。。。比较出不同后应该如何更改或添加新的任务呢?我菜!

#6


许多应用会动态读取配置文件的。另外一些可能会引起应用重新启动(reload)

#7


任务运行的时候加载一次配置文件就行了,至于任务的定时运行,简单的用TimerTask就可以了,复杂点的用Quartz

#8


任务运行的时候加载一次配置文件就行了,至于任务的定时运行,简单的用TimerTask就可以了,复杂点的用Quartz

#9


quatz中这种情况好象叫"有状态的作业",真不知道如何实现啊!
麻烦有经验的高手给个例子,感激不尽!

#10


引用 2 楼 laorer 的回复:
quatz,研究下,半天差不多能搞定,
也可能一天以上


赞成!

#11


那里有quartz比较好的实例!学习他开始从实例(带注释)比较好把!

#12


写了两个类.版主要是有耐心,就看一看,完善一下,应该可以用

package houlei.mission;

import java.io.Serializable;

/**
 * 该类是每个任务的封装Bean类.成员变量,应该是每个任务执行条件.<br>
 * 每个任务都应该有它的唯一标识符id,或者名字name也可以.其他的成员变量(像任务时间之类的),版主自己填写就可以了<br>
 * @author 侯磊
 */
public class Mission implements Serializable{

private static final long serialVersionUID = 1L;
private String id;
private String SQL;

public Mission(String id, String sql) {
this.id = id;
SQL = sql;
}
public boolean canExcute(){
//这里添加任务可以执行的条件.一般是根据成员变量的内容,以及当前时间来决定返回值.
return true;
}
public String getSQL() {
return SQL;
}

public String getId() {
return id;
}

}

#13



package houlei.mission;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 任务管理器的封装类型
 * @author 侯磊
 */
public class MissionManager {
private Map missions = Collections.synchronizedMap(new HashMap());
private File config;
private CheckThread checker;
public MissionManager(File config){
this.config=config;
checker= new CheckThread();
}
private void loadConfigFile(File config){

//这里添加读取配置文件的代码.创建Mission对象
//调用addMission方法更新missions的内容.
//调用removeMission将配置文件中不存在的任务删除.
}
public void addMission(String id,Mission mission){
//missions的Key存放Mission的id(字符串类型);Value存放Mission对象.
missions.put(id,mission);
}
public void removeMission(String id){
missions.remove(id);
}
public void startup(){
checker.start();
}
public void shutdown(){
checker.stop();
}
/**
 * 任务的执行器线程.用于执行任务.
 * @author 侯磊
 */
private class ExcutorThread implements Runnable{
private Mission mission;
private Thread instance;
private boolean running=false;
public ExcutorThread(Mission mission) {
this.mission = mission;
}

public void run() {
//这里添加任务的执行代码.如果有循环结构,要注意条件中添加running变量
mission.getSQL();//...
}
public void start(){
if(running)return;
running=true;
instance = new Thread(this);
instance.start();
}
public void stop(){
if(running){
running=false;
instance.interrupt();
// instance.join();
}
}
}

/**
 * 任务管理器的巡查线程.<br>
 * 用于检测配置文件是否变动,以及任务是否可以执行.
 * @author 侯磊
 */
private class CheckThread implements Runnable{
private long lastReadTime=0L;
private Thread instance = new Thread(this);
private boolean running=false;
public void run() {
while(running){
//检查配置文件的时间.
File file = new File(config.getAbsolutePath());
if(file.lastModified()>lastReadTime){
loadConfigFile(file);
lastReadTime=file.lastModified();
}
//检查任务是否可以执行
synchronized (missions) {
for(Iterator itr = missions.keySet().iterator();itr.hasNext()&&running;){
String id = itr.next().toString();
Mission mission = (Mission)missions.get(id);
if(mission.canExcute()){
new ExcutorThread(mission).start();
}
}
}
try {
Thread.sleep(1000);//巡查间隔
} catch (InterruptedException e) { }
}
}
public void start(){
if(running)return;
running=true;
instance.start();
}
public void stop(){
if(running){
running=false;
instance.interrupt();
// instance.join();
}
}
}
}

#14


感激先尝试下...!

#15


Timer time = new Timer(); 
FabuAttempet aa=new FabuAttempet(); 
List list =aa.getData();//获得所有任务 
for (int i = 0; i < list.size(); i++) { 
HashMap map = (HashMap) list.get(i);//每个任务里面的数据 
FabuAttempetTask fabuTask = new FabuAttempetTask(map); 
time.scheduleAtFixedRate(fabuTask, fabuTask.getFirstTime(), fabuTask 
.getCycleTime()); 


以上是要执行的所有任务,每个任务都需要1个Task所以要循环!我应该加到那里呢?

#16


学到东西了,好帖,先楼主了,收藏了,

#17


楼主截止到2008-06-17 15:50:24的汇总数据:
发帖数:1
结贴数:0
结贴率: 0.00%