2017-08-03 247 views
1

我有一個小程序可以做以下事情: 主線程和線程t1週期性地請求一個東西,一個按鈕將停止這兩個。從另一個線程調用timer.cancel()之後,TimerTask不會立即停止嗎?

public class HttpsConn { 
    private static boolean stop = false; 
    private static Timer t = null; 

    public static void main(String[] arg) { 
     t = new Timer(); 
     A a = new A(); 
     t.schedule(a, 0, 1000); 
     B b = new B(); 
     Thread t1 = new Thread(b); 
     t1.start(); 
    } 
    static class A extends TimerTask { 
     @Override 
     public void run() { 
      if (stop) 
       t.cancel();  //this.cancel(); 
      System.out.println("something to do"); 
     } 
    } 
    static class B extends A implements Runnable { 
     @Override 
     public void run() { 
      System.out.println("simulate an operation from Swing Applet (click RESET button) to interrupt the thread."); 
      stop = true; 
     } 
    } 
} 

我除了結果:

something to do 
simulate an operation from Swing Applet (click RESET button) to interrupt the thread. 

我能得到什麼:

something to do 
simulate an operation from Swing Applet (click RESET button) to interrupt the thread. 
something to do 

我發現類似的問題here,回答說:電話從該時期內取消() ,但在這裏似乎不起作用。 那麼如何避免意外運行? t.cancel()this.cancel()之間的區別是什麼?他們導致相同的結果。 謝謝!

+0

它似乎取消工作正常,但。它取消,然後打印該行,因爲它應該。 – matt

+0

至於你後來的問題。 'this.cancel()'取消TimerTask,這意味着Timer可以繼續工作。 t.cancel()取消定時器。 – matt

+0

另外,我想阻止你使用applet。 – matt

回答

0

您的A計劃運行,初始延遲時間爲0,後續延遲時間爲1秒。

第一個something to do是在延遲0之後首次執行。 stop標誌尚未設置,因此它只是打印並退出。

一秒鐘後,它再次被Timer調用。它檢查stop標誌,取消定時器(因爲B已執行並設置它)並打印第二個something to do。它不應該再次運行,因爲定時器任務現在已被取消。

爲了避免這種看似怪異的行爲,你可以使用類似:

 if (!stop) { 
      System.out.println("something to do"); 
     } else { 
      t.cancel();  //this.cancel(); 
     } 

記住cancel只有取消Timer,它不會中止Runnable的執行。

+0

謝謝。這樣看起來很容易:)。那麼你能幫我解答我的第二個問題嗎? @matt評論我的帖子,但我仍然無法弄清楚定時器被取消和timertask被取消之間的區別。如果定時器終止,則時間任務將不會繼續;如果timertask被終止,則定時器甚至不會死亡。所以?有什麼區別? – feng

+0

@feng - 在'schedule'調用中傳遞的參數的控制下,每當'Timer'決定這樣做時,''TimerTask''(你稱之爲'a'')就會被執行。它運行正常,並在每次通過「運行」方法調用時終止。定時器將繼續調用它,直到它停止。我希望這會讓事情更清楚。 – OldCurmudgeon

相關問題