等待Timer在Java中完成

我正在使用java.util.Timer来安排定期任务。 有一次,我想关闭它, 等待它完成

Timer.cancel()将阻止任何未来的任务运行。 如何确保当前没有任何任务正在运行(或等待它们,如果它们是?)

我可以引入外部同步机制,但我不知道它们如何涵盖所有情况。 例如,如果我在任务中的某个监视器上进行同步,我仍然会错过任务刚刚开始执行但没有使用监视器的情况。

等待所有任务真正完成的建议做法是什么,包括当前正在运行的任务?

您最好使用ScheduledExecutorService而不是Timer来安排定期任务。 ScheduledExecutorService提供了一个shutdown()方法,该方法将执行任何挂起的任务。 然后,您可以调用awaitTermination()以等待shutdown()完成。

如下所示可能有助于您的需求 –

 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(); } } }