公司做項目,其中涉及到一個遊戲的業務邏輯,需要使用定時類去執行,在使用Timer的時候,發現總是出現奇怪的問題。
如下代碼:
package com.yifeng.test22;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class RunLoter {
private static Timer timer = new Timer();
static public class Mytest1 extends TimerTask {
@Override
public void run() {
// 這裏不幹別的只是睡覺
try {
System.out.println("Mytest1運行了,當前時間爲" + new Date());
Thread.sleep(20000);
System.out.println("Mytest2運行了,當前時間爲" + new Date());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
static public class Mytest2 extends TimerTask {
@Override
public void run() {
System.out.println("Mytest2運行了,當前時間爲" + new Date());
}
}
public static void main(String[] args) throws ParseException {
Mytest1 mytest1=new Mytest1();
Mytest2 mytest2=new Mytest2();
timer.schedule(mytest1, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-11 09:49:40"));
timer.schedule(mytest2, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-11 09:49:40"));
}
}
我去,Test2 竟然沒按照時間執行,而是在test1執行結束後纔去執行的。
究其原因:
這是因爲Timer基本處理模型是單線程調度的任務隊列模型,Timer不停地接受調度任務,所有任務接受Timer調度後加入TaskQueue,TimerThread不停地去TaskQueue中取任務來執行.此種方式的不足之處爲當某個任務執行時間較長,以致於超過了TaskQueue中下一個任務開始執行的時間,會影響整個任務執行的實時性。
你可以試用scheduleAtFixedRate方法,它會讓任務儘量保證在規定的時間頻率執行,如:定的時間頻率是2s,因爲系統繁忙,之後的2.5秒後任務才得以執行第二次,然後,Timer記下了這個延遲,並嘗試在下一個任務的時候彌補這個延遲,那麼,1.5秒後,任務將執行.