摆动计时器:不要依赖摆动计时器。问题标记;和并发问题

时间:2013-01-30 17:48:39

标签: java swing timer

首先让我感到震惊的是:System.currentTimeMillis()我认为非常准确,给出了long值,以及SwingTimers请求int参数的位置;它是什么意思?不要认为SwingTimers是准确的吗?

2)假设用SwingTimer定时一个字需要x毫秒;如果我们重复一项任务(突出显示单词,如卡拉OK应用程序),我会包含以下代码:

               /*see the time taken for each letter*/                    
                 int tik=(int) delay / words[index].length();
 /* make adjustment(subtract few millisecs)  as per the time taken by each word*/
                   if(tik <69)
                    timer.setDelay((int) (delay / words[index].length())-3);
                   if(tik >=69&&tik<=149)
                    timer.setDelay((int) (delay / words[index].length())-6);
                   else if(tik <=150)
                       timer.setDelay((int) (delay / words[index].length())-9);
                   else if(tik >150)
                   timer.setDelay((int) (delay / words[index].length())-100);

工作安静很好,但我绝对肯定我不能依赖这个,因为时间,长度可能会改变!如何克服这个问题?因为几毫秒的变化可能给我带来灾难性的后果。

3)同时我想知道卡拉OK制造商和播放器软件采用哪种技术?非常准确。

3 个答案:

答案 0 :(得分:6)

  

与此同时,我想知道卡拉OK制造商和卡拉OK制造商采用哪种技术?播放器软件如何?

我猜卡拉OK软件有一个输入节拍和时间签名的引擎,并且音符持续时间(整个音符,半音符,四分音符等)与歌词一起输入。

引擎计算每季度音符的毫秒数,并根据计算一次显示一个字母。

我怀疑必须手动输入音符持续时间,但如果引擎收听音乐并确定音乐的音符持续时间,则会非常有效。

保持完美时间

正如您已经确定的那样,Thread.sleep()和Swing计时器不能保持完美的时间。

如果你想要精确的时间,你将不得不建立自己的计时器。这是一个版本。

    public void moreAccurateTimer(int period) { // Sleep time in
                                                // milliseconds
        long beforeTime, timeDiff, sleepTime;
        beforeTime = System.currentTimeMillis();
        boolean running = true;
        while (running) {
            doStuff();

            timeDiff = System.currentTimeMillis() - beforeTime;
            sleepTime = period - timeDiff;

            if (sleepTime <= 0L) { // Even if doing stuff took longer than
                                    // period
                sleepTime = 5L; // sleep some anyway
            }

            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
            }

            beforeTime = System.currentTimeMillis();
        }
    }

答案 1 :(得分:6)

基于计算机/操作系统时钟计时的方法,无论时间源的准确程度如何 - 通常都存在缺陷,尽管在某些情况下,时间不正常可能会有效需要准确无误。

一种聪明的方法是从你想要同步的东西中获取时间信息 - 所以对于卡拉OK,从播放音频中获取时间并响应。这种方法自然避免了常见的麻烦:处理(用户启动)音频播放中的暂停以及音频和系统硬件之间的微小时间偏差。

答案 2 :(得分:2)

我们必须接受我们永远无法准时到达;我们可以早或晚。

多年来一直考虑,每秒24帧已经制作了连续看电影。而现在,我们已经升至59 FPS?因此,+ / - 20ms左右对人类来说是不明显的。

如果您的应用程序需要在电子级别上进行精确计时,请考虑调度和并发性可能会导致各种问题。当我在Y2K周围的C ****** e工作时,这是一个非常重要的事情,并且经常受到视频设置的影响等等。时序相关问题的伪像显示为延迟,故障和音调不准确。

假设我们使用while循环方法(原谅我的伪代码):

/ ** psuedocode ** /

something.idLikeToTriggerNow();

time_now = time_then = system.getMicroseconds();

while(time_now&lt; time_then + 1000){

// NOP

time_now = system.getMicroseconds();

}

something.idLikeToTrigger1msLater();

/ **结束psuedocode ** /

这只能保证您在进入后一毫秒之前不会离开。但是,你可能会以某种方式中断获取系统时间,并在半秒后退出,而不是因为Norton Antivirus。我的观点与Java无关,尤其如此。此外,即使while循环工作正常,下一个操作可能会被你的NVidia驱动程序延迟,也许,这可能比你在宏观计划中的Java应用程序具有更高的优先级。

在Java中是否有一种方法可以使两个事件更容易相隔1毫秒,容差可能为+/- 100us?