等待计时器在 Java 中完成
Posted
技术标签:
【中文标题】等待计时器在 Java 中完成【英文标题】:Waiting for a Timer to finish in Java 【发布时间】:2010-11-22 05:44:30 【问题描述】:我正在使用java.util.Timer 来安排定期任务。在某一时刻,我想关闭它,然后等待它完成。
Timer.cancel() 将阻止任何未来的任务运行。我如何确保当前没有运行任何任务(或者等待它们运行?)
我可以引入外部同步机制,但我看不出它们如何涵盖所有情况。例如,如果我在任务中的某个监视器上进行同步,我仍然会错过任务刚开始执行但没有占用监视器的情况。
等待所有任务真正完成(包括当前正在运行的任务)的推荐做法是什么?
【问题讨论】:
【参考方案1】:您最好使用ScheduledExecutorService 而不是计时器来安排您的定期任务。 ScheduledExecutorService 提供了一个shutdown() 方法,它将执行任何挂起的任务。然后您可以调用 awaitTermination() 来等待 shutdown() 完成。
【讨论】:
+1。或者,如果由于某种原因必须使用Timer
,那么您可以使用 Condition (java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/…) 来同步事件上的两个线程(例如完成计划任务)。
是的,Effective Java(第 2 版)中的第 68 条建议将 ScheduledThreadPoolExecutor 作为 Timer 的更灵活的替代品。 +1 提及这一点,因为要求推荐的做法。
或使用 CountdownLatch 等***.com/questions/289434/…【参考方案2】:
以下内容可能对您的需求有所帮助-
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();
【讨论】:
你应该使用Thread.sleep(...)
而不是Thread.currentThread().sleep(...)
,因为它是一个静态方法;您的代码可能会诱使您执行someOtherThread.sleep(...)
不休眠someOtherThread
。以上是关于等待计时器在 Java 中完成的主要内容,如果未能解决你的问题,请参考以下文章