Timer定時(shí)器用法詳解
發表時(shí)間:2019-7-6
發布人(rén):融晨科技
浏覽次數:40
先看API和(hé / huò)結論:
/**
timer總結:
Timer timer = new Timer(); //其中會調用this("Timer-" + serialNumber());, 即它以(yǐ)Timer+序列号爲(wéi / wèi)該定時(shí)器的(de)名字
Timer timer = new Timer(String name); //以(yǐ)name作爲(wéi / wèi)該定時(shí)器的(de)名字
Timer timer = new Timer(boolean isDeamon); //是(shì)否将此定時(shí)器作爲(wéi / wèi)守護線程執行
Timer timer = new Timer(name, isDeamon); //定時(shí)器名字, 是(shì)否爲(wéi / wèi)守護線程
注意:
默認無參構造器将會使該線程作爲(wéi / wèi)非守護線程, 即使主線程已經停止并銷毀, 隻要(yào / yāo)該線程還存在(zài), 則程序不(bù)會停止
即下面的(de)所有執行的(de)任務, 無論是(shì)否是(shì)定時(shí)還是(shì)非定時(shí), 隻要(yào / yāo)主線程一旦結束, 那麽該定時(shí)器立即同主線程一起銷毀
以(yǐ)下所有的(de)task都是(shì)TimerTask的(de)子(zǐ)類
所有time都是(shì)Date類型的(de)日期
所有delay和(hé / huò)period都是(shì)long類型的(de)延遲時(shí)間, 單位爲(wéi / wèi)毫秒
timer.schedule(task, time); 在(zài)time時(shí)間執行task任務1次
timer.schedule(task, delay); 在(zài)延遲delay毫秒後執行task任務1次
timer.schedule(task, firstTime, period); 在(zài)firsttime時(shí)間執行task1次,之(zhī)後定期period毫秒時(shí)間執行task, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 不(bù)會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.schedule(task, delay, period); 在(zài)延遲delay後執行task1次,之(zhī)後定期period毫秒時(shí)間執行task, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 不(bù)會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.scheduleAtFixedRate(task, firstTime, period); 在(zài)firstTime時(shí)間執行task一次, 以(yǐ)後每隔period毫秒執行1次, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.scheduleAtFixedRate(task, delay, period); 在(zài)delay毫秒後執行task一次, 以(yǐ)後每隔period毫秒執行1次, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
區别:test4();
timer.schedule(task, firstTime, period);
timer.scheduleAtFixedRate(task, firstTime, period);
從test4運行結果可以(yǐ)看到(dào), 如果開始時(shí)間在(zài)過去, 則
schedule會表現出(chū)隻從當前時(shí)間開始,
scheduleAtFixedRate會把之(zhī)前沒有來(lái)得及執行的(de)任務全都執行, 感覺像之(zhī)前一直有在(zài)執行一樣
區别: test5()
timer.schedule(task, time);
timer.schedule(task, delay);
其中, 如果time時(shí)間爲(wéi / wèi)過去時(shí)間, 則該任務會馬上(shàng)執行, 如果爲(wéi / wèi)将來(lái)時(shí)間, 則會等待時(shí)間到(dào)來(lái)再執行
如果傳入的(de)是(shì)delay, 則delay不(bù)可以(yǐ)爲(wéi / wèi)負數, 負數報錯, 正數代表未來(lái)的(de)delay毫秒以(yǐ)後執行
小結:
時(shí)間如果爲(wéi / wèi)過去時(shí)間, 則所有scheduke和(hé / huò)scheduleAtFixedRate都會立即執行
并且scheduke不(bù)會執行過去的(de)任務, 而(ér)scheduleAtFixedRate則會把過去的(de)任務全都執行, 即按照固定時(shí)間執行一樣
isDeamon決定是(shì)否該Timer以(yǐ)守護線程存在(zài)
timer.purge();
先看英文描述:
Removes all cancelled tasks from this timer's task queue. Calling this method has no effect>import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
timer總結:
Timer timer = new Timer(); //其中會調用this("Timer-" + serialNumber());, 即它以(yǐ)Timer+序列号爲(wéi / wèi)該定時(shí)器的(de)名字
Timer timer = new Timer(String name); //以(yǐ)name作爲(wéi / wèi)該定時(shí)器的(de)名字
Timer timer = new Timer(boolean isDeamon); //是(shì)否将此定時(shí)器作爲(wéi / wèi)守護線程執行
Timer timer = new Timer(name, isDeamon); //定時(shí)器名字, 是(shì)否爲(wéi / wèi)守護線程
注意:
默認無參構造器将會使該線程作爲(wéi / wèi)非守護線程, 即使主線程已經停止并銷毀, 隻要(yào / yāo)該線程還存在(zài), 則程序不(bù)會停止
即下面的(de)所有執行的(de)任務, 無論是(shì)否是(shì)定時(shí)還是(shì)非定時(shí), 隻要(yào / yāo)主線程一旦結束, 那麽該定時(shí)器立即同主線程一起銷毀
以(yǐ)下所有的(de)task都是(shì)TimerTask的(de)子(zǐ)類
所有time都是(shì)Date類型的(de)日期
所有delay和(hé / huò)period都是(shì)long類型的(de)延遲時(shí)間, 單位爲(wéi / wèi)毫秒
timer.schedule(task, time); 在(zài)time時(shí)間執行task任務1次
timer.schedule(task, delay); 在(zài)延遲delay毫秒後執行task任務1次
timer.schedule(task, firstTime, period); 在(zài)firsttime時(shí)間執行task1次,之(zhī)後定期period毫秒時(shí)間執行task, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 不(bù)會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.schedule(task, delay, period); 在(zài)延遲delay後執行task1次,之(zhī)後定期period毫秒時(shí)間執行task, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 不(bù)會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.scheduleAtFixedRate(task, firstTime, period); 在(zài)firstTime時(shí)間執行task一次, 以(yǐ)後每隔period毫秒執行1次, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
timer.scheduleAtFixedRate(task, delay, period); 在(zài)delay毫秒後執行task一次, 以(yǐ)後每隔period毫秒執行1次, 時(shí)間如果爲(wéi / wèi)過去時(shí)間, 會執行過去沒有執行的(de)任務, 但是(shì)會馬上(shàng)執行
區别:test4();
timer.schedule(task, firstTime, period);
timer.scheduleAtFixedRate(task, firstTime, period);
從test4運行結果可以(yǐ)看到(dào), 如果開始時(shí)間在(zài)過去, 則
schedule會表現出(chū)隻從當前時(shí)間開始,
scheduleAtFixedRate會把之(zhī)前沒有來(lái)得及執行的(de)任務全都執行, 感覺像之(zhī)前一直有在(zài)執行一樣
區别: test5()
timer.schedule(task, time);
timer.schedule(task, delay);
其中, 如果time時(shí)間爲(wéi / wèi)過去時(shí)間, 則該任務會馬上(shàng)執行, 如果爲(wéi / wèi)将來(lái)時(shí)間, 則會等待時(shí)間到(dào)來(lái)再執行
如果傳入的(de)是(shì)delay, 則delay不(bù)可以(yǐ)爲(wéi / wèi)負數, 負數報錯, 正數代表未來(lái)的(de)delay毫秒以(yǐ)後執行
小結:
時(shí)間如果爲(wéi / wèi)過去時(shí)間, 則所有scheduke和(hé / huò)scheduleAtFixedRate都會立即執行
并且scheduke不(bù)會執行過去的(de)任務, 而(ér)scheduleAtFixedRate則會把過去的(de)任務全都執行, 即按照固定時(shí)間執行一樣
isDeamon決定是(shì)否該Timer以(yǐ)守護線程存在(zài)
timer.purge();
先看英文描述:
Removes all cancelled tasks from this timer's task queue. Calling this method has no effect on the behavior of the timer, but eliminates the references to the cancelled tasks from the queue. If there are no external references to these tasks, they become eligible for garbage collection.
Most programs will have no need to call this method. It is designed for use by the rare application that cancels a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the number of cancelled tasks.
Note that it is permissible to call this method from within a a task scheduled on this timer.
Returns:
the number of tasks removed from the queue.
Since:
1.5
即purge();對實際的(de)timer的(de)任務執行不(bù)會有影響, 它僅僅隻會移除所有被取消的(de)任務隊列的(de)引用以(yǐ)方便垃圾回收, 通常不(bù)用調用此方法, 隻有任務數非常多(n + c log n)的(de)時(shí)候, 可以(yǐ)調用此方法以(yǐ)時(shí)間換取空間.
timer.cancel();
Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it.
Note that calling this method from within the run method of a timer task that was invoked by this timer absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this timer.
This method may be called repeatedly; the second and subsequent calls have no effect.
即cancel();停止該timer, 并且丢棄所有綁定的(de)任務, 但不(bù)幹預當前正在(zài)執行的(de)任務。一旦timer停止了(le/liǎo), 那麽其執行線程将會優雅終止, 并且該timer不(bù)可以(yǐ)再綁定task任務了(le/liǎo)
*/
public class TimerTest {
public static void main(String[] args) {
// test1(); //測試schedule功能
// test2(); //測試所有scheduleAtFixedRate功能
// test3(); //測試isDeamon對Timer的(de)影響
// test4(); //測試AtFixedRateSchedule和(hé / huò)schedule區别
// test5(); //測試schedule在(zài)過去時(shí)間的(de)表現, 如果firstTime是(shì)過去時(shí)間, 則立即執行, 如果是(shì)未來(lái)時(shí)間, 則會等待時(shí)間到(dào)之(zhī)後執行, 如果是(shì)傳入延遲時(shí)間, 則延遲時(shí)間不(bù)能爲(wéi / wèi)負數, 否則報錯
// test6();
test7();
}
public static void test1()
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執行了(le/liǎo)1次");
}
}, 1000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執行了(le/liǎo)2次");
}
}, getDelayTime(2));
//第3和(hé / huò)第4個(gè)task的(de)執行順序是(shì)不(bù)确定的(de),因爲(wéi / wèi)時(shí)間片的(de)切換導緻的(de)微小差别
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執行了(le/liǎo)3次");
}
}, getDelayTime(3), 1000); //3, -3
timer.schedule(new TimerTask() {
@Override
public void run() {
System.err.println("執行了(le/liǎo)4次");
}
}, 1000, 1000);
}
public static void test2()
{
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("AtFixedRate1");
}
}, getDelayTime(1), 1000);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("AtFixedRate2");
}
}, 2000, 1000);
}
public static void test3()
{
Timer timer = new Timer("isDeamon", true);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("isDeamon");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, getDelayTime(2), 2000);
}
public static void test4()
{
Timer timer = new Timer("AtFixedRate", false);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("schedule");
}
}, getDelayTime(-5), 2000);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("scheduleAtFixedRate");
}
}, getDelayTime(-5), 2000);
}
public static void test5()
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("測試時(shí)間爲(wéi / wèi)過去時(shí)間和(hé / huò)将來(lái)時(shí)間對schedule的(de)影響");
}
}, getDelayTime(-5)); //立即執行
}
public static void test6()
{
//purge: 清洗, 淨化
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("測試purge1");
}
}, getDelayTime(1), 1000);
System.out.println("purge: "+timer.purge());
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("測試purge2");
}
}, getDelayTime(1), 1000);
}
public static void test7()
{
//将7和(hé / huò)6對比看
Timer timer = new Timer();
class MyTimerTask extends TimerTask{
@Override
public void run() {
System.out.println("測試purge1");
this.cancel();
}
}
for(int i = 0; i<100; i++)
{
MyTimerTask mt = new MyTimerTask();
timer.schedule(mt, getDelayTime(1), 1000);
mt.cancel();
}
// timer.cancel();
System.out.println("此時(shí)可以(yǐ)移除取消的(de)任務數爲(wéi / wèi)100個(gè): "+timer.purge());
/*timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("我現在(zài)還可以(yǐ)執行~~");
}
}, getDelayTime(2));*/
for(int i = 0; i<100; i++)
{
MyTimerTask mt = new MyTimerTask();
mt.cancel();
timer.schedule(mt, getDelayTime(1), 1000);
}
System.out.println("此時(shí)可以(yǐ)移除取消的(de)任務數爲(wéi / wèi)100個(gè): "+timer.purge());
///
}
//給定一個(gè)時(shí)間,返回給定多久以(yǐ)後的(de)Date
public static Date getDelayTime(int howlong)
{
Calendar cld = Calendar.getInstance();
cld.set(Calendar.SECOND, howlong+cld.get(Calendar.SECOND));
return cld.getTime();
}
}
其中難點隻有這(zhè)個(gè)purge的(de)使用,下面這(zhè)篇文章詳細解釋了(le/liǎo)purge在(zài)queue隊列非常大(dà)時(shí)如何避免内存洩漏的(de)
Java定時(shí)任務Timer調度器【三】 注意事項(任務精确性與内存洩漏)
這(zhè)裏有個(gè)問題待考慮:爲(wéi / wèi)什麽purge()返回值一直是(shì)0,我已經将TimerTask任務取消,但是(shì)返回的(de)purge()還是(shì)0.這(zhè)點很奇怪。
其他(tā)類似文章:
定時(shí)器Timer