先看API和結(jié)論:
/**
?? ?timer總結(jié):
?? ?Timer timer = new Timer();?? ?//其中會(huì)調(diào)用this("Timer-" + serialNumber());, 即它以Timer+序列號(hào)為該定時(shí)器的名字
?? ?Timer timer = new Timer(String name);?? ?//以name作為該定時(shí)器的名字
?? ?Timer timer = new Timer(boolean isDeamon);?? ?//是否將此定時(shí)器作為守護(hù)線程執(zhí)行
?? ?Timer timer = new Timer(name, isDeamon);?? ?//定時(shí)器名字, 是否為守護(hù)線程
?? ?
?? ?注意:
?? ?默認(rèn)無參構(gòu)造器將會(huì)使該線程作為非守護(hù)線程, 即使主線程已經(jīng)停止并銷毀, 只要該線程還存在, 則程序不會(huì)停止
?? ?即下面的所有執(zhí)行的任務(wù), 無論是否是定時(shí)還是非定時(shí), 只要主線程一旦結(jié)束, 那么該定時(shí)器立即同主線程一起銷毀
?? ?
?? ?以下所有的task都是TimerTask的子類
?? ?所有time都是Date類型的日期
?? ?所有delay和period都是long類型的延遲時(shí)間, 單位為毫秒
?? ?timer.schedule(task, time);?? ??? ??? ??? ??? ?在time時(shí)間執(zhí)行task任務(wù)1次
?? ?timer.schedule(task, delay);?? ??? ??? ??? ?在延遲delay毫秒后執(zhí)行task任務(wù)1次
?? ?timer.schedule(task, firstTime, period);?? ?在firsttime時(shí)間執(zhí)行task1次,之后定期period毫秒時(shí)間執(zhí)行task,?? ?時(shí)間如果為過去時(shí)間, 不會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
?? ?timer.schedule(task, delay, period);?? ??? ?在延遲delay后執(zhí)行task1次,之后定期period毫秒時(shí)間執(zhí)行task, ?? ?時(shí)間如果為過去時(shí)間, 不會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
?? ?
?? ?timer.scheduleAtFixedRate(task, firstTime, period);?? ??? ?在firstTime時(shí)間執(zhí)行task一次, 以后每隔period毫秒執(zhí)行1次, 時(shí)間如果為過去時(shí)間, 會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
?? ?timer.scheduleAtFixedRate(task, delay, period);?? ??? ??? ?在delay毫秒后執(zhí)行task一次, 以后每隔period毫秒執(zhí)行1次, 時(shí)間如果為過去時(shí)間, 會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
?? ?
?? ?區(qū)別:test4();
?? ?timer.schedule(task, firstTime, period);
?? ?timer.scheduleAtFixedRate(task, firstTime, period);
?? ?從test4運(yùn)行結(jié)果可以看到, 如果開始時(shí)間在過去, 則
?? ??? ?schedule會(huì)表現(xiàn)出只從當(dāng)前時(shí)間開始,
?? ??? ?scheduleAtFixedRate會(huì)把之前沒有來得及執(zhí)行的任務(wù)全都執(zhí)行, 感覺像之前一直有在執(zhí)行一樣
?? ??? ?
?? ?區(qū)別: test5()
?? ?timer.schedule(task, time);
?? ?timer.schedule(task, delay);
?? ?其中, 如果time時(shí)間為過去時(shí)間, 則該任務(wù)會(huì)馬上執(zhí)行, 如果為將來時(shí)間, 則會(huì)等待時(shí)間到來再執(zhí)行
?? ?如果傳入的是delay, 則delay不可以為負(fù)數(shù), 負(fù)數(shù)報(bào)錯(cuò), 正數(shù)代表未來的delay毫秒以后執(zhí)行
?? ?
?? ?
?? ?小結(jié):
?? ??? ?時(shí)間如果為過去時(shí)間, 則所有scheduke和scheduleAtFixedRate都會(huì)立即執(zhí)行
?? ??? ?并且scheduke不會(huì)執(zhí)行過去的任務(wù), 而scheduleAtFixedRate則會(huì)把過去的任務(wù)全都執(zhí)行, 即按照固定時(shí)間執(zhí)行一樣
?? ??? ?isDeamon決定是否該Timer以守護(hù)線程存在
?? ?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();對(duì)實(shí)際的timer的任務(wù)執(zhí)行不會(huì)有影響, 它僅僅只會(huì)移除所有被取消的任務(wù)隊(duì)列的引用以方便垃圾回收, 通常不用調(diào)用此方法, 只有任務(wù)數(shù)非常多(n + c log n)的時(shí)候, 可以調(diào)用此方法以時(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, 并且丟棄所有綁定的任務(wù), 但不干預(yù)當(dāng)前正在執(zhí)行的任務(wù)。一旦timer停止了, 那么其執(zhí)行線程將會(huì)優(yōu)雅終止, 并且該timer不可以再綁定task任務(wù)了
?*/
再看測試代碼:
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
timer總結(jié):
Timer timer = new Timer(); //其中會(huì)調(diào)用this("Timer-" + serialNumber());, 即它以Timer+序列號(hào)為該定時(shí)器的名字
Timer timer = new Timer(String name); //以name作為該定時(shí)器的名字
Timer timer = new Timer(boolean isDeamon); //是否將此定時(shí)器作為守護(hù)線程執(zhí)行
Timer timer = new Timer(name, isDeamon); //定時(shí)器名字, 是否為守護(hù)線程
注意:
默認(rèn)無參構(gòu)造器將會(huì)使該線程作為非守護(hù)線程, 即使主線程已經(jīng)停止并銷毀, 只要該線程還存在, 則程序不會(huì)停止
即下面的所有執(zhí)行的任務(wù), 無論是否是定時(shí)還是非定時(shí), 只要主線程一旦結(jié)束, 那么該定時(shí)器立即同主線程一起銷毀
以下所有的task都是TimerTask的子類
所有time都是Date類型的日期
所有delay和period都是long類型的延遲時(shí)間, 單位為毫秒
timer.schedule(task, time); 在time時(shí)間執(zhí)行task任務(wù)1次
timer.schedule(task, delay); 在延遲delay毫秒后執(zhí)行task任務(wù)1次
timer.schedule(task, firstTime, period); 在firsttime時(shí)間執(zhí)行task1次,之后定期period毫秒時(shí)間執(zhí)行task, 時(shí)間如果為過去時(shí)間, 不會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
timer.schedule(task, delay, period); 在延遲delay后執(zhí)行task1次,之后定期period毫秒時(shí)間執(zhí)行task, 時(shí)間如果為過去時(shí)間, 不會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
timer.scheduleAtFixedRate(task, firstTime, period); 在firstTime時(shí)間執(zhí)行task一次, 以后每隔period毫秒執(zhí)行1次, 時(shí)間如果為過去時(shí)間, 會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
timer.scheduleAtFixedRate(task, delay, period); 在delay毫秒后執(zhí)行task一次, 以后每隔period毫秒執(zhí)行1次, 時(shí)間如果為過去時(shí)間, 會(huì)執(zhí)行過去沒有執(zhí)行的任務(wù), 但是會(huì)馬上執(zhí)行
區(qū)別:test4();
timer.schedule(task, firstTime, period);
timer.scheduleAtFixedRate(task, firstTime, period);
從test4運(yùn)行結(jié)果可以看到, 如果開始時(shí)間在過去, 則
schedule會(huì)表現(xiàn)出只從當(dāng)前時(shí)間開始,
scheduleAtFixedRate會(huì)把之前沒有來得及執(zhí)行的任務(wù)全都執(zhí)行, 感覺像之前一直有在執(zhí)行一樣
區(qū)別: test5()
timer.schedule(task, time);
timer.schedule(task, delay);
其中, 如果time時(shí)間為過去時(shí)間, 則該任務(wù)會(huì)馬上執(zhí)行, 如果為將來時(shí)間, 則會(huì)等待時(shí)間到來再執(zhí)行
如果傳入的是delay, 則delay不可以為負(fù)數(shù), 負(fù)數(shù)報(bào)錯(cuò), 正數(shù)代表未來的delay毫秒以后執(zhí)行
小結(jié):
時(shí)間如果為過去時(shí)間, 則所有scheduke和scheduleAtFixedRate都會(huì)立即執(zhí)行
并且scheduke不會(huì)執(zhí)行過去的任務(wù), 而scheduleAtFixedRate則會(huì)把過去的任務(wù)全都執(zhí)行, 即按照固定時(shí)間執(zhí)行一樣
isDeamon決定是否該Timer以守護(hù)線程存在
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();對(duì)實(shí)際的timer的任務(wù)執(zhí)行不會(huì)有影響, 它僅僅只會(huì)移除所有被取消的任務(wù)隊(duì)列的引用以方便垃圾回收, 通常不用調(diào)用此方法, 只有任務(wù)數(shù)非常多(n + c log n)的時(shí)候, 可以調(diào)用此方法以時(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, 并且丟棄所有綁定的任務(wù), 但不干預(yù)當(dāng)前正在執(zhí)行的任務(wù)。一旦timer停止了, 那么其執(zhí)行線程將會(huì)優(yōu)雅終止, 并且該timer不可以再綁定task任務(wù)了
*/
public class TimerTest {
public static void main(String[] args) {
// test1(); //測試schedule功能
// test2(); //測試所有scheduleAtFixedRate功能
// test3(); //測試isDeamon對(duì)Timer的影響
// test4(); //測試AtFixedRateSchedule和schedule區(qū)別
// test5(); //測試schedule在過去時(shí)間的表現(xiàn), 如果firstTime是過去時(shí)間, 則立即執(zhí)行, 如果是未來時(shí)間, 則會(huì)等待時(shí)間到之后執(zhí)行, 如果是傳入延遲時(shí)間, 則延遲時(shí)間不能為負(fù)數(shù), 否則報(bào)錯(cuò)
// test6();
test7();
}
public static void test1()
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執(zhí)行了1次");
}
}, 1000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執(zhí)行了2次");
}
}, getDelayTime(2));
//第3和第4個(gè)task的執(zhí)行順序是不確定的,因?yàn)闀r(shí)間片的切換導(dǎo)致的微小差別
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("執(zhí)行了3次");
}
}, getDelayTime(3), 1000); //3, -3
timer.schedule(new TimerTask() {
@Override
public void run() {
System.err.println("執(zhí)行了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í)間為過去時(shí)間和將來時(shí)間對(duì)schedule的影響");
}
}, getDelayTime(-5)); //立即執(zhí)行
}
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和6對(duì)比看
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í)可以移除取消的任務(wù)數(shù)為100個(gè): "+timer.purge());
/*timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("我現(xiàn)在還可以執(zhí)行~~");
}
}, 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í)可以移除取消的任務(wù)數(shù)為100個(gè): "+timer.purge());
///////////////////////////////////////
}
//給定一個(gè)時(shí)間,返回給定多久以后的Date
public static Date getDelayTime(int howlong)
{
Calendar cld = Calendar.getInstance();
cld.set(Calendar.SECOND, howlong+cld.get(Calendar.SECOND));
return cld.getTime();
}
}
其中難點(diǎn)只有這個(gè)purge的使用,下面這篇文章詳細(xì)解釋了purge在queue隊(duì)列非常大時(shí)如何避免內(nèi)存泄漏的
Java定時(shí)任務(wù)Timer調(diào)度器【三】 注意事項(xiàng)(任務(wù)精確性與內(nèi)存泄漏)
這里有個(gè)問題待考慮:為什么purge()返回值一直是0,我已經(jīng)將TimerTask任務(wù)取消,但是返回的purge()還是0.這點(diǎn)很奇怪。
其他類似文章:
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com