2011-07-12 50 views
5

在以下情況下會發生什麼情況?java定時器計劃任務

Timer t = new Timer(); 
t.schedule(...); 
t = new Timer(); 

具體而言,會發生什麼情況,我已經安排在計時器T後我分配的定時器的新實例到t的任務?

回答

7

他們不會消失。每個Timer對象都與後臺進程關聯。即使您在程序中刪除了所有對Timer的引用,後臺進程仍將繼續運行(它擁有它自己對該對象的引用)。因此,該對象不會被垃圾收集。

詳情請參閱official documentation

對應每一個Timer對象是用於執行所有的計時器的任務,順序...最後活引用一個Timer對象消失,並在所有未完成的任務已完成執行一個後臺線程,定時器的任務執行線程正常終止(並且成爲垃圾收集的對象)。但是,這可能需要很長時間才能發生。

2

它將運行沒有任何問題。唯一的是,如果你不能取消第一個計時器(如果你真的想取消它)

0

API docs for Timer使我相信失去對定時器的引用根本不會影響它。看起來,任何計劃任務仍然肯定會被執行。定時器實例不能被收集,應用程序無法關閉,直到用該定時器計劃的最後一項任務完成執行。文檔摘錄如下:

「在最後一次對Timer對象的實時引用消失並且所有未完成的任務已經完成執行之後,計時器的任務執行線程將優雅地終止(並且可能會被垃圾收集)。任意執行線程不會作爲一個守護進程線程運行,所以它可以阻止應用程序終止。如果調用者想要快速終止一個定時器的任務執行線程,調用者應該調用定時器取消方法「。

0

例如

private ScheduledExecutorService scheduler; 
private AccurateScheduledRunnable periodic; 
private ScheduledFuture<?> periodicMonitor; 
private int taskPeriod = 30; 
private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); 
private SimpleDateFormat sdfHour = new SimpleDateFormat("HH"); 

。 。 。

scheduler = Executors.newSingleThreadScheduledExecutor(); 
      periodic = new AccurateScheduledRunnable() { 

       private final int ALLOWED_TARDINESS = 200; 
       private int countRun = 0; 
       private int countCalled = 0; 

       @Override 
       public void run() { 
        countCalled++; 
        if (this.getExecutionTime() < ALLOWED_TARDINESS) { 
         countRun++; 
         dateNext = new java.util.Date(); 
         dateLast = new java.util.Date(); 
         long tme = dateNext.getTime(); 
         tme += (taskPeriod * 60) * 1000; 
         dateNext.setTime(tme); 
         //System.out.println(""); 
         //System.out.println(""); 
         //System.out.println("Next Sheduled Time at : " + sdf.format(dateNext)); 
         //System.out.println("Periodic Cycle In : " + (countRun) + "/" + countCalled + " at " + sdf.format(dateLast)); 
         //ti.displayMessage(null, " Running Sheduled Task at " + sdf.format(new Date()), TrayIcon.MessageType.NONE); 
         distAppInfo(); 
        } 
       } 
      }; 
      periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.MINUTES); 
      periodic.setThreadMonitor(periodicMonitor); 

and implements監視器返回f.e.剩餘時間到下一個Shedule

long she = periodicMonitor.getDelay(TimeUnit.SECONDS); 

和監控

abstract class AccurateScheduledRunnable implements Runnable { 

    private ScheduledFuture<?> thisThreadsMonitor; 

    public void setThreadMonitor(ScheduledFuture<?> monitor) { 
     this.thisThreadsMonitor = monitor; 
    } 

    protected long getExecutionTime() { 
     long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS); 
     return delay; 
    } 
} 
0

這將取決於其Timer.schedule(..),您計劃使用方法。如果定時器被設置爲重複執行,那麼將一個新的Timer實例分配給t不會導致垃圾收集,因爲定時器線程將保持活動狀態。如果將該定時器設置爲一次執行,則該對象將被收集垃圾..at至少這是文檔所說的..