2011-07-12 20 views
5

次の場合はどうなりますか?java timerスケジュールされたタスク

具体的には、私はタイマーの新しいインスタンスをtに割り当てた後、タイマーtでスケジュールしたタスクはどうなりますか?

答えて

7

彼らは離れません。各Timerオブジェクトは、バックグラウンドプロセスに関連付けられています。プログラム内のTimerへの参照をすべて削除しても、バックグラウンドプロセスは引き続き実行されます(オブジェクトへの参照を保持しています)。このため、オブジェクトはガベージコレクションの対象にはなりません。

詳細はofficial documentationを参照してください。

各タイマオブジェクトに対応するのは、すべてのタイマーのタスクを順番に実行するために使用される単一のバックグラウンドスレッドです。タイマーオブジェクトへの最後のライブ参照がなくなり、タイマーのタスク実行スレッドは正常に終了します(ガベージコレクションの対象となります)。しかしながら、これは任意に発生するのに長い時間がかかります。

2

これは問題なく動作します。唯一のことは、最初のタイマーをキャンセルできない場合です(実際にキャンセルしたい場合)

0

API docs for 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); 

となります。それはあなたが利用する予定でTimer.schedule(..)メソッドを依存することになる次の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

を監視します。タイマーが繰り返し実行されるように設定されている場合、タイマーの新しいインスタンスをtに割り当てても、タイマースレッドはアクティブのままですので、ガベージコレクションは発生しません。タイマーを1回実行するように設定すると、オブジェクトはガベージコレクションされます。少なくともそれはドキュメントが言うことです。

関連する問題