【问题标题】:How to cancel a timer.schedule() invocation early如何提前取消 timer.schedule() 调用
【发布时间】:2013-09-27 07:08:57
【问题描述】:

我已经安排了一个方法在未来的某个日期运行;但是,在该日期之前可能会或可能不会发生某些事件,这意味着我希望在指定日期之前运行该方法;我怎样才能做到这一点?我目前有:

Timer timer = new Timer();
TimerTask task = new TaskToRunOnExpriation();
timer.schedule(task, myCalendarObject.getTime());

我将在我的应用程序中运行许多这些TimerTask,如果发生某种情况,请停止它们的特定实例?

编辑 我只想取消给定事件的单个Timer,有没有办法管理Timers 的身份以便我可以轻松找到并停止它?

【问题讨论】:

  • 试过timer.cancel() ?
  • 如果正在启动数千个计时器,我如何确定合适的计时器?
  • 你如何找到那些你想停止的计时器?

标签: java time timer


【解决方案1】:

在 C# 中我会说使用委托,但这在 Java 中不是一个选项。我会解决这个想法:

class Timers
{
    Timer timer1;
    Timer timer2;
    ArrayList<Timer> timerList;

    public Timers()
    {
        // schedule the timers
    }

    // cancel timers related to an event
    public void eventA()
    {
        timer1.cancel();
        timer2.cancel();
    }

    public void eventB()
    {
        for(Timer t : timerList)
            t.cancel();
    }
}

【讨论】:

    【解决方案2】:

    使用此调度方法。

    public void schedule(TimerTask task,Date firstTime,long period)

    task--这是要安排的任务。

    firstTime--这是第一次执行任务。

    周期--这是连续任务执行之间的时间(以毫秒为单位)

    【讨论】:

    • OP 想要取消计时器而不是安排它们。
    【解决方案3】:

    如果您有数千个,您应该使用ScheduledExecutorService 来池线程,而不是使用每个计时器使用一个线程的 Timer。

    执行器服务在调度任务时返回的ScheduledFutures也有cancel方法来取消底层任务:future.cancel(true);

    至于取消正确的任务,您可以将期货存储在 Map&lt;String, Future&gt; 中,以便您可以通过名称或 ID 访问它们。

    【讨论】:

    • 对于需要几千个未来的应用程序,调度程序是否使用了典型/足够数量的线程?即x for x in ScheduledExecutorServe scheduler = Executors.newScheduledThreadPool(x);
    • @alh,我想强调一下@assylias 所说的话。 you could store the futures in a Map&lt;String, Future&gt; so you can access them by name or id for example - 如果您想在需要时对其进行控制,这是将某些内容存储在集合中的常用方法。如果您在识别堆栈时遇到问题,要关闭哪个项目,则说明您选择了错误的应用架构。尝试重新考虑事情。通常,您使用从基本类扩展的自定义类进行 colltcion,在其中添加功能以您想要的方式识别元素
    • @alh 尝试考虑有多少任务可以并行运行并使用该数字 + 一个小缓冲区(除非导致数字太高 - 你可能不想说 100 个线程 - 但是这在很大程度上取决于您的用例)。
    【解决方案4】:

    我在android中使用Timer来更新进度条。这是我的一些代码,希望它可以帮助你:

    Timer timer ;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
            //....
    
            timer = new Timer();
            timer.schedule(new TimerTask() {
                public void run() {
                    updateLogoBarHandler.sendEmptyMessage(0);
                    Log.e("SplashActivity","updating the logo progress bar...");
             }}, 0, 50);
    
           //.....
    
    }
    
    //here do the timer.cancel();
    private Handler updateLogoBarHandler = new Handler() {
        public void handleMessage(Message msg) {
            if(logobarClipe.getLevel() < 10000){
                    logobarClipe.setLevel(logobarClipe.getLevel() + 50);  
            }else{
                    timer.cancel();
            }  
            super.handleMessage(msg);
       }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 2019-05-18
      • 1970-01-01
      相关资源
      最近更新 更多