当前位置:  开发笔记 > 编程语言 > 正文

可重置的Java计时器

如何解决《可重置的Java计时器》经验,为你挑选了2个好方法。

我想在java中有一个带有可重置时间的java.utils.Timer.我需要在X秒内设置一次性事件.如果在创建计时器和X秒之间没有任何反应,则事件正常发生.

但是,如果在X秒过去之前,我决定事件应该在Y秒之后发生,那么我希望能够告诉计时器重置其时间,以便事件在Y秒内发生.例如,计时器应该能够执行以下操作:

Timer timer = new Timer();  
timer.schedule(timerTask, 5000); //Timer starts in 5000 ms (X)

//At some point between 0 and 5000 ms...  
setNewTime(timer, 8000);  //timerTask will fire in 8000ms from NOW (Y).

我没有看到使用utils计时器的方法,就像你调用cancel(),你不能再次安排它.

我接近复制此行为的唯一方法是使用javax.swing.Timer并涉及停止原始计时器,并创建一个新计时器.即:

timer.stop();
timer = new Timer(8000, ActionListener);
timer.start();

有没有更简单的方法??



1> Chris Jester..:

根据Timer文档,在Java 1.5以后,您应该更喜欢ScheduledThreadPoolExecutor.(您可能希望使用易于使用来创建此执行程序;它创建的东西很像.)Executors.newSingleThreadScheduledExecutor()Timer

很酷的是,当你安排任务(通过调用schedule())时,它会返回一个ScheduledFuture对象.您可以使用它来取消计划任务.然后,您可以自由地提交具有不同触发时间的新任务.

ETA:Timer链接到的文档没有说明任何内容ScheduledThreadPoolExecutor,但是OpenJDK版本有这样的说法:

Java 5.0引入了java.util.concurrent包,其中一个并发实用程序 ScheduledThreadPoolExecutor是一个线程池,用于以给定的速率或延迟重复执行任务.它实际上是Timer/ TimerTask 组合的更通用的替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类化TimerTask(只是实现Runnable).ScheduledThreadPoolExecutor使用一个线程进行配置 使其等效于 Timer.


使用`myScheduledThreadPoolExecutor.getQueue().clear()`删除所有尚未运行的计划任务,但不能将此技术用于`Executors.newSingleThreadScheduledExecutor()`,而是必须实例化`new ScheduledThreadPoolExecutor( 1)`因为只有接口方法暴露在Executor返回的对象上.

2> David Sykes..:

如果你Timer只有一个任务要执行,那么我建议继承它:

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

public class ReschedulableTimer extends Timer
{
    private Runnable  task;
    private TimerTask timerTask;

    public void schedule(Runnable runnable, long delay)
    {
        task = runnable;
        timerTask = new TimerTask()
        {
            @Override
            public void run()
            {
                task.run();
            }
        };
        this.schedule(timerTask, delay);
    }

    public void reschedule(long delay)
    {
        timerTask.cancel();
        timerTask = new TimerTask()
        {
            @Override
            public void run()
            {
                task.run();
            }
        };
        this.schedule(timerTask, delay);
    }
}

您将需要处理代码以添加错误使用的检查,但它应该实现您想要的.在ScheduledThreadPoolExecutor似乎并不具有内置的支持,要么重新安排现有任务,但类似的做法应该工作有作为.

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有