TimerTask.cancel() 与 Timer.cancel() 的区别
? ? ? ? TimerTask.cancel() 與 Timer.cancel()?都可以理解為清除任務隊列中的任務。看源碼
? ? ? ? TimerTask.cancel()?
/*** Cancels this timer task. If the task has been scheduled for one-time* execution and has not yet run, or has not yet been scheduled, it will* never run. If the task has been scheduled for repeated execution, it* will never run again. (If the task is running when this call occurs,* the task will run to completion, but will never run again.)** <p>Note that calling this method from within the <tt>run</tt> method of* a repeating timer task absolutely guarantees that the timer task will* not run again.** <p>This method may be called repeatedly; the second and subsequent* calls have no effect.** @return true if this task is scheduled for one-time execution and has* not yet run, or this task is scheduled for repeated execution.* Returns false if the task was scheduled for one-time execution* and has already run, or if the task was never scheduled, or if* the task was already cancelled. (Loosely speaking, this method* returns <tt>true</tt> if it prevents one or more scheduled* executions from taking place.)*/public boolean cancel() {synchronized(lock) {boolean result = (state == SCHEDULED);state = CANCELLED;return result;}}? ? ? ? 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.** <p>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.** <p>This method may be called repeatedly; the second and subsequent* calls have no effect.*/public void cancel() {synchronized(queue) {thread.newTasksMayBeScheduled = false;queue.clear();queue.notify(); // In case queue was already empty.}}? ? ? ? 從源碼中可以看出,TimerTask.cancel() 只是將當前正在執行的任務終止,state = CANCELLED,return true;如果當前任務已經執行結束,也是將當前任務終止,return false。由此我們也可以看出,當同一項任務調用多次 .cancel() 方法時,該方法只會有效執行一次。而Timer.cancel() 是將當前定時任務中的所有正在運行的任務都清除,使timer沒有可執行的任務。所以兩者的區別之處在,TimerTask.cancel() 只是將當前任務終止,也可以理解為從定時任務(任務隊列)中清除掉,但實際上并沒有對Timer進行任何操作,所以在調用 TimerTask.cancel() 時,Timer定時任務(任務隊列)中的其它任務還是正常執行,不會影響其它任務的正常執行,而Timer.cancel() 是將整個定時任務(任務隊列)的中的所有任務全部清除。
? ? ? ?是不是調用了cancel()后任務會立即結束呢?我們從TimerTask.cancel源碼的注釋中也可以看到,If the task is running when this call occurs, the task will run to completion, but will never run again. 大概意思就是 當調用TimerTask.cancel() 方法時,該任務正在運行中,這項任務會正常運行到結束,但不會再次運行。同樣的在Timer.cancel源碼的注釋中也可以看到一個類似的解釋Does not interfere with a currently executing task (if it exists)。翻譯為中文大概就是 不干擾當前正在運行的任務(如果存在)。說明當調用cancel()方法后,當前正在運行的任務還能正常運行下去,還有一口氣能把這項任務執行完畢,當任務執行完畢后,下次不會再執行,而沒有開始執行的任務也不會執行。
測試
測試1:task1和task2都不執行cancel()
public class TestTimerCancel {public static void main(String args[]) throws ParseException, InterruptedException {Timer timer = new Timer();TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間1:" + this.scheduledExecutionTime());// this.cancel();// timer.cancel();}};TimerTask task2 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間2:" + this.scheduledExecutionTime());// this.cancel();// timer.cancel();}};long delay1 = 1000; // 任務延遲毫秒數long delay2 = 2000; // 任務延遲毫秒數long period = 1000; // 任務間隔毫秒數timer.schedule(task1, delay1, period);timer.schedule(task2, delay2, period);} }測試結果:兩個任務正常執行
任務執行時間1:1547991032207 任務執行時間2:1547991033208 任務執行時間1:1547991033208 任務執行時間1:1547991034209 任務執行時間2:1547991034209 任務執行時間2:1547991035224 任務執行時間1:1547991035224 任務執行時間1:1547991036225 任務執行時間2:1547991036225 任務執行時間2:1547991037226 任務執行時間1:1547991037226 任務執行時間1:1547991038227 任務執行時間2:1547991038227測試2:僅task1調用TimerTask.cancel()
TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間1:" + this.scheduledExecutionTime());this.cancel();} };測試結果:task1只執行了1次,調用TimerTask.cancel()不影響其它任務的正常執行
任務執行時間1:1547991235852 任務執行時間2:1547991236854 任務執行時間2:1547991237857 任務執行時間2:1547991238859 任務執行時間2:1547991239860 任務執行時間2:1547991240875 任務執行時間2:1547991241890 任務執行時間2:1547991242895 任務執行時間2:1547991243900 任務執行時間2:1547991244906測試3:僅task1調用Timer.cancel()
TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間1:" + this.scheduledExecutionTime());timer.cancel();} };測試結果:僅task1執行了一次,task2沒有執行。
任務執行時間1:1547991575545?測試4:僅task2調用TimerTask.cancel()
TimerTask task2 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間2:" + this.scheduledExecutionTime());this.cancel();} };測試結果:task2僅執行了一次,task1正常進行固定延遲執行
任務執行時間1:1547991944113 任務執行時間2:1547991945126 任務執行時間1:1547991945126 任務執行時間1:1547991946130 任務執行時間1:1547991947144 任務執行時間1:1547991948147 任務執行時間1:1547991949161 任務執行時間1:1547991950162 任務執行時間1:1547991951175測試5:僅task2調用Timer.cancel()
TimerTask task2 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間2:" + this.scheduledExecutionTime());timer.cancel();} };測試結果:task1 和task2都僅執行了一次。由于task1早于task2執行,task2在執行時task1處于執行完畢或者執行中,所以task2執行完后,整個任務隊列清除。task2僅能執行一次,task1的執行次數跟task2執行結束時間有關,task2執行結束時間越晚task1執行次數越多。
任務執行時間1:1547992056180 任務執行時間2:1547992057187測試6:task1調用TimerTask.cancel(),task2調用Timer.cancel()
TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間1:" + this.scheduledExecutionTime());this.cancel();// timer.cancel();} }; TimerTask task2 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間2:" + this.scheduledExecutionTime());// this.cancel();timer.cancel();} };測試結果:task1和task2都僅執行一次
任務執行時間1:1547992543756 任務執行時間2:1547992544753測試7:task1調用Timer.cancel(),task2調用TimerTask.cancel()
TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間1:" + this.scheduledExecutionTime());// this.cancel();timer.cancel();} }; TimerTask task2 = new TimerTask() {@Overridepublic void run() {System.out.println("任務執行時間2:" + this.scheduledExecutionTime());this.cancel();// timer.cancel();} };測試結果:僅task1執行了1次
任務執行時間1:1547992633651?
總結
以上是生活随笔為你收集整理的TimerTask.cancel() 与 Timer.cancel() 的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生产线生产工序自动化信息化管理系统软件生
- 下一篇: Markdown的使用 Markdown