13

java.util.Timerを使用して定期的なタスクをスケジュールしています。ある時点で、シャットダウンして、終了するのを待ちたいと思います。

Timer.cancel()は、将来のタスクの実行を防ぎます。現在実行中のタスクがないことを確認するにはどうすればよいですか(実行中の場合は待機しますか?)

外部同期メカニズムを導入することはできますが、それらがすべてのケースをどのようにカバーできるかはわかりません。たとえば、タスク内の一部のモニターで同期した場合でも、タスクが実行を開始したばかりでモニターを取得しなかった場合は見逃します。

現在実行中のタスクを含め、すべてのタスクが実際に完了するまで待機するための推奨される方法は何ですか?

4

2 に答える 2

23

定期的なタスクをスケジュールするには、タイマーの代わりにScheduledExecutorServiceを使用することをお勧めします。ScheduledExecutorServiceは、保留中のタスクを実行するshutdown()メソッドを提供します。次に、awaitTermination()を呼び出して、shutdown()が終了するのを待つことができます。

于 2009-08-24T11:00:35.100 に答える
0

以下のようなものがあなたのニーズを助けるかもしれません-

import java.util.Timer;
import java.util.TimerTask;

public class TimerGracefulShutdown {
    public static void main(String[] args) throws InterruptedException {
        //This is a synchronization helper class
        SyncHelper syncHelper = new SyncHelper();

        TimerManager myTimerManager = new TimerManager(syncHelper);

        //Try stopping timer after 5 seconds (it wont stop until the 30 seconds sleep of timertask does not finish)
        Thread.currentThread().sleep(5000);
        System.out.println("Going to stop my timer now");
        myTimerManager.stopTimer();
        System.out.println("Cancelled timer");
    }
}

class TimerManager {

    SyncHelper syncHelper;
    Timer timer;

    public TimerManager(SyncHelper syncHelper) {
        this.syncHelper = syncHelper;
        startTimer();
    }

    private void startTimer() {
        timer = new Timer(true);
        TimerTask myTask = new MyTimerTask(syncHelper);
        timer.scheduleAtFixedRate(myTask, 0, 100000);
    }

    public void stopTimer() {
        try {
            syncHelper.testAndSetOrReset("acquire");
        } catch(Exception e) {
            e.printStackTrace();
        }

        //Shutdown the timer here since you know that your timertask is not executing right now.
        timer.cancel();
        try {
            syncHelper.testAndSetOrReset("release");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class MyTimerTask extends TimerTask {

    private SyncHelper syncHelper;

    public MyTimerTask(SyncHelper syncHelper) {
        this.syncHelper = syncHelper;
    }

    public void run() {
        try {
            syncHelper.testAndSetOrReset("acquire");
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        System.out.println("Over here");
        try {
            Thread.currentThread().sleep(30000);
        } catch(Exception e) {

        }
        System.out.println("Done sleeping");

        //Finally release the helper.
        try {
            syncHelper.testAndSetOrReset("release");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class SyncHelper {

    private int index = 0;

    public synchronized void testAndSetOrReset(String command) throws Exception {

        if("acquire".equals(command)) { 
            if(index == 1) {
                wait();
            }
            index++;
        } else if("release".equals(command)) {
            index--;
            notifyAll();
        }
    }
}
于 2009-08-24T12:38:21.313 に答える