首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接受时间源的Java - Timer类

接受时间源的Java - Timer类
EN

Stack Overflow用户
提问于 2014-05-23 03:19:45
回答 2查看 347关注 0票数 0

我需要替换接受时间源的java.util.Timer或java.util.concurrent.ScheduledExecutorService,以便将其从系统时间、中移除。我使用这个计时器周期性地执行一个方法,但是当应用程序处于“活动”模式时,需要由系统时间驱动,而当应用程序处于“回放”模式时,需要一些其他源。

我确实看到了一些第三方库,比如番石榴秒表,其功能类似于我所要求的功能,但由于我正在开发的信息系统的策略,我更喜欢Java的原生功能。

我可能最终不得不写我自己的,但我在这里问,因为这似乎是一个需要,许多人会.无论是在使用具有替代时间传递概念的应用程序时,还是在使用嵌入式计时器测试单元时。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-24 00:35:47

如果其他人需要它,这是我最后得到的解决方案。

代码语言:javascript
复制
public interface TimeSource {
    long currentTimeMillis();
}

public class AlternateTimeSource implements TimeSource {

    long currentTime = 0;       

    public AlternateTimeSource() {
    }

    public setTime(long time) {
        if (time > currentTime) currentTime = time;
    }

    @Override
    public long currentTimeMillis() {
        return currentTime;
    }
}

public class SystemTimeSource implements TimeSource {

    @Override
    public long currentTimeMillis() {
        return System.currentTimeMillis();
    }
}

class SourcedTimerThread extends Thread {

    TimeSource reference_;
    TimerTask task_;
    long period_;
    long executionTime_;
    boolean done = false;

    SourcedTimerThread(TimeSource reference,TimerTask task,long delay,long period) {
        reference_     = reference;
        task_          = task;
        period_        = period >= 0 ? period : 0;
        executionTime_ = reference_.currentTimeMillis() + (delay >= 0 ? delay : 0);
        setName("SourcedTimerThread_"+reference_.getClass().getSimpleName());
        start();
    }

    public void cancel() {
        done = true;
        interrupt();
    }

    public void run() {

        long currentTime;

        while (!done) {
            try {
                currentTime = reference_.currentTimeMillis();
                if (executionTime_>currentTime) { 
                    // Task hasn't yet fired; wait
                    sleep(1);                   }
                else {
                    task_.run();
                    if (period_ > 0) {
                        // Repeating task, reschedule
                        executionTime_ = ((period_ < 0) ? currentTime-period_ : executionTime_ + period_);
                    }
                    else {
                        // Non-repeating task, done
                        break;
                    }
                }
            } catch (InterruptedException e) {
            }
        }
    }
}

用法:

代码语言:javascript
复制
// Build source
TimeSource source = null;
if (alternate) {
    source = new AlternateTimeSource();
}
else {
    source = new SystemTimeSource();
}

// Configure timer
SourcedTimerThread t = new SourcedTimerThread(source,new TimerTask() {
    @Override
    void run() {
        System.out.println("Yay!");
    }
}, delayMs, periodMs);

// Drive timer if necessary
if (alternate) {
    // Drive timer based on alternate source such as data
    source.setTime(dataRecord.getTime());
}

// When ready to cleanup
t.cancel();
票数 0
EN

Stack Overflow用户

发布于 2014-05-23 03:48:41

通过执行以下操作,可以使用自定义时间源实现java.util.concurrent.ScheduledExecutorService

计算自定义时间源和系统时间之间的偏移量或增量(初始化时),并在ScheduledExecutorService实现中保持增量。当调用schedule (以及接口中的类似方法)时,使用与初始化时计算的相同的偏移量,并在所提供的TimeUnits上应用这些偏移量。这样--您可以依赖于调度程序的现有实现。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23820454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档