关于java.util.Timer的TimerTask的cancel问题

maskice 2009-08-21 07:57:57
首先看看我的定时器的代码:
public class CleanTimer{
private Timer timer;
/**
* Creates a new instance of CleanTimer
*/
public CleanTimer() {
}

public void StartService(Date delaytime, Long cycletime) {
try{
timer = new Timer();

timer.scheduleAtFixedRate(new CleanTimerTask(), delaytime, cycletime);

} catch(Exception ex) {
ex.printStackTrace();

}
}

}

public class CleanTimerTask extends TimerTask {
/** Creates a new instance of CleanTimerTask */
public CleanTimerTask() {
}

public void run() {
try{
CleanTask.ExecuteCleanFunction();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
现在有个问题,我的任务是变的,有增有减,增加的时候,我可以new CleanTimer调用StartService()方法添加一个,但是当需要回收掉以前增加的某个TASK的时候,就不知道该怎么做了
Timer 和 TimerTask 都有cancel方法,但是怎么用呀,我怎么才能找到我要cancel掉的Task或者是Timer呢?
看Timer的API中,它的构造方法中有一个Timer(String name)的,说明写的是:创建一个新计时器,其相关的线程具有指定的名称。但是指定名称有说明用呀,我刚开始以为以后可以根据这个名称把所创建的Timer get出来,可以翻到后面的方法中,也没有说是能根据名称找出所创建的方法呀,请教高人,我该怎么做,先谢谢了!在线等!
...全文
1522 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
maskice 2009-08-23
  • 打赏
  • 举报
回复
呵呵,这两天加班加糊涂了,犯了好低级的错误,把对象ID都能搞错了,今天来了一看,狂晕中,之前停不了任务是因为通过当前对象获取到关联对象的ID来停用的,而关联对象的ID在这里是同一个,所以停用第二次的时候它会报错。其实代码是没有问题的,呵呵,更改下代码即可,分享给大家,希望对同样遇到该问题的同胞们有帮助,另外感谢阿牛同学的热心帮忙!结贴!
原:

mapTimer.put("T"+dct.getCdid().getCdid().toString(),new Timer());
mapTimer.get("T"+dct.getCdid().getCdid().toString()).scheduleAtFixedRate(ctt, delaytime, cycletime);

mapTimer.get("T"+dct.getCdid().getCdid().toString()).cancel();
mapTimer.remove("T"+dct.getCdid().getCdid().toString());

更改:

mapTimer.put("T"+dct.getCtid().toString(),new Timer());
mapTimer.get("T"+dct.getCtid().toString()).scheduleAtFixedRate(ctt, delaytime, cycletime);

mapTimer.get("T"+dct.getCtid().toString()).cancel();
mapTimer.remove("T"+dct.getCtid().toString());

islandrabbit 2009-08-21
  • 打赏
  • 举报
回复
我按楼主的思路写了个简单测试程序,运行后是没问题的,楼主再好好检查检查代码吧:

CleanTimer:

public class CleanTimer {

private static Map<String,Timer> mapTimer=new HashMap<String,Timer>();

private CleanTimer() {
}

public static void StartService(String taskName) {
try{
mapTimer.put(taskName,new Timer());
CleanTimerTask ctt=new CleanTimerTask(taskName);
mapTimer.get(taskName).scheduleAtFixedRate(ctt, 0, 1000);

} catch(Exception ex) {
ex.printStackTrace();

}
}

public static void RemoveTimer(String taskName){
try{
mapTimer.get(taskName).cancel();
mapTimer.remove(taskName);
}catch(Exception e){
e.printStackTrace();
}
}
}


CleanTimerTask:

public class CleanTimerTask extends TimerTask {

private String taskName;

public CleanTimerTask(String taskName) {
this.taskName = taskName;
}

public void run() {
System.out.println(taskName+" is running.");
}
}


主程序:

public class CleanTimerDriver {

public static void main(String[] args) throws InterruptedException {

CleanTimer.StartService("Task1");

CleanTimer.StartService("Task2");

Thread.sleep(3000);

CleanTimer.RemoveTimer("Task1");

CleanTimer.RemoveTimer("Task2");

}

}
islandrabbit 2009-08-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 maskice 的回复:]
本人水平有限呀,还需麻烦大虾帮忙看看...
[/Quote]

楼主太谦虚了!从代码看,好像没什么毛病。有什么异常吗?
maskice 2009-08-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 islandrabbit 的回复:]
首先,要使用Timer的cancel方法。这样会终止这个timer,终止timer下排定的TimerTask,允许现在正在执行的TimerTask继续执行,直到结束,然后终止timer的线程。

看了一下,感到那个代码是不会满足楼主的需求的。具体分析请看下面代码的注解:
Java codepublicclass CleanTimer{private Timer timer;//这里有问题//可改为://private List<Timer> timerList = new ArrayList<Timer>();//在这个基础上,楼主再作相应的修改就可以了。/**
* Creates a new instance of CleanTimer*/public CleanTimer() {
}publicvoid StartService(Date delaytime, Long cycletime) {try{
timer=new Timer();//这里有问题//每次开始新的任务//timer会被赋予新值//原来的timer和它的TimerTask还有线程就无法终止了。
timer.scheduleAtFixedRate(new CleanTimerTask(), delaytime, cycletime);

}catch(Exception ex) {
ex.printStackTrace();

}
}

}
[/Quote]

public class CleanTimer{
private static Map<String,Timer> mapTimer=new HashMap<String,Timer>();
/**
* Creates a new instance of CleanTimer
*/
public CleanTimer() {
}

public static void StartService(DctCleanTab dct,Date delaytime, Long cycletime) {
try{
mapTimer.put("T"+dct.getCdid().getCdid().toString(),new Timer());
CleanTimerTask ctt=new CleanTimerTask();
ctt.setDctParam(dct);
mapTimer.get("T"+dct.getCdid().getCdid().toString()).scheduleAtFixedRate(ctt, delaytime, cycletime);
DctLogger.info(dct.getTaskname()+"任务实例成功启动!");
} catch(Exception ex) {
ex.printStackTrace();
DctLogger.error(dct.getTaskname()+"任务实例启动失败:"+ex.getMessage(),ex.getCause());
}
}

public static void RemoveTimer(DctCleanTab dct){
try{
mapTimer.get("T"+dct.getCdid().getCdid().toString()).cancel();
mapTimer.remove("T"+dct.getCdid().getCdid().toString());
DctLogger.info(dct.getTaskname()+"任务实例停用成功!");
}catch(Exception e){
e.printStackTrace();
DctLogger.error(dct.getTaskname()+"任务实例停用失败:"+e.getMessage(),e.getCause());
}
}

}

谢谢帮忙,但是你的意思我没有完全明白,你看下我写的代码,是不是这样的:

public class CleanTimerTask extends TimerTask {
private DctCleanTab dctParam;
/** Creates a new instance of CleanTimerTask */
public CleanTimerTask() {
}

public void run() {
try{

ExecuteCleanBean.ExecuteCleanFunction(dctParam);
System.out.println("StrParam:"+dctParam.getTaskname()+new Date());

} catch(Exception ex) {
ex.printStackTrace();
}
}

public DctCleanTab getDctParam() {
return dctParam;
}

public void setDctParam(DctCleanTab dctParam) {
this.dctParam = dctParam;
}
}

但是这样写,当我根据DctCleanTab对象来删除Timer时,也是不行的,我建立了两个DctCleanTab 对象,然后依次启动,启动后,在任务开始执行后,我调用CleanTimer.RemoveTimer(DctCleanTab dct)删除对应的两个定时器,但是,总是只能删掉其中一个。另外一个始终删不掉,好只能删掉后启动的定时器。另外一个始终在运行,晕了,本人水平有限呀,还需麻烦大虾帮忙看看...
islandrabbit 2009-08-21
  • 打赏
  • 举报
回复
首先,要使用Timer的cancel方法。这样会终止这个timer,终止timer下排定的TimerTask,允许现在正在执行的TimerTask继续执行,直到结束,然后终止timer的线程。

看了一下,感到那个代码是不会满足楼主的需求的。具体分析请看下面代码的注解:

public class CleanTimer{
private Timer timer; //这里有问题
//可改为:
//private List<Timer> timerList = new ArrayList<Timer>();
//在这个基础上,楼主再作相应的修改就可以了。

/**
* Creates a new instance of CleanTimer
*/
public CleanTimer() {
}

public void StartService(Date delaytime, Long cycletime) {
try{
timer = new Timer(); //这里有问题
//每次开始新的任务
//timer会被赋予新值
//原来的timer和它的TimerTask还有线程就无法终止了。

timer.scheduleAtFixedRate(new CleanTimerTask(), delaytime, cycletime);

} catch(Exception ex) {
ex.printStackTrace();

}
}

}


67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧