关于java中使用timer进行线程调度
在使用timer进行线程调度时出现这样一种问题,求大侠们指教
主程序入口
[code="java"]
public class App {
public static void main(String[] args) throws Exception {
Timer fileTransportTimer=new Timer("fileTransportTimer");
fileTransportTimer.scheduleAtFixedRate(new FileTransportTimer(), 3000, 1000*30);
}
}
[/code]
定时任务线程
[code="java"]
public class FileTransportTimer extends TimerTask{
public static boolean isRun = false;
public void run() {
if (isRun) {
return;
}
isRun = true;
SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
logger.info("开始扫描并发送文件!");
try{
//扫描目录,判断是否有待发送的文件
String path=AppStart.cache.getLocalFilePath();
File root=new File(path);
if(!root.isDirectory()){
throw new Exception("file root is not a directory");
}
File[] files=root.listFiles();
for(int i=0;i<files.length;i++){
File tmp=files[i];
if(tmp.isFile()){
try { MQHandler.sendFile(tmp);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
}
logger.info("发送文件任务结束!");
}catch(Exception e){
logger.error("发送文件任务错误!");
e.printStackTrace();
}finally{
isRun=false;
}
}
}
[/code]
这里已经进行了运行状态的控制,程序确实也是这样的一个执行结果,但每次在执行完成后
都会有这样的日志输出
[color=red]
2013-02-21 16:01:08 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:01:08 com.rf.util.MQHandler文件War3x.mpq高优先级
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:20 com.rf.thread.FileTransportTimer发送文件任务结束!
2013-02-21 16:05:38 com.rf.thread.FileTransportTimer开始扫描并发送文件!
2013-02-21 16:05:38 com.rf.thread.FileTransportTimer发送文件任务结束!
[/color]
处理文件的时候线程正在运行,新的定时任务不会执行到文件处理的代码部分就会return掉,但当第一个定时任务执行完成后,一下子就打印出了好多后面的这些日志,这点不太明白???
[quote]public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)安排指定的任务在指定的延迟后开始进行重复的固定速率执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。
在固定速率执行中,根据已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他背景活动)而延迟了某次执行,则将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
[/quote]
定时任务是30s一次,你第一个定时任务执行了4分钟,应该是很多定时任务阻塞住了...
我猜的~
你这里timer调度是单个后台线程,运行过程是这样的:
当第一次执行,扫描到文件时,执行发送文件任务,任务执行大概花费时间1000*30*9毫秒,根据scheduleAtFixedRate定义的“
在固定速率执行中,根据已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)”,当任务执行完成后,isRun=false,下一次执行时因为没有文件发送了,任务执行时间很短,所以后面的任务按照之前本应该开始执行的任务,但被第一个长时间任务占用了执行时间,将会快速执行,直到之前遗留任务全部执行完毕后,按照period即1000*30定时执行下次任务。
这里你要关注的是,30s一次的任务,1分钟将会安排执行两次,但是如果一次任务超过了30s,后面的任务会安排,但是不会执行,直到上次任务执行,才好进行下一次任务,FixedRate,表示它是按时间周期来安排频率,执行任务的次数正好是时间周期的倒数,不知道这样说,你明白没有?