1ms Java定时器延迟是否太快?

1ms Java定时器延迟是否太快?,java,timer,Java,Timer,每次触发时,它都会运行一个超级快速的操作,基本上不需要任何时间:基本上,它会获取当前的毫秒经过值并将其递增,同时在以毫秒为键的映射中进行快速查找 你认为1毫秒的延迟会太快吗?这会使系统陷入困境吗?尝试使用这种超快计时器有什么危险吗?可能。在当代计算机上,一毫秒内会发生很多事情,所以这取决于很多事情。您可能应该计算出可接受的最低速率,然后在1和该数字之间选择合理的值。这将每天执行86400000次左右。这对你想要实现的目标有意义吗 编辑:正如问题注释中的一些注释所示,如果您假设计时器总是以您提供的

每次触发时,它都会运行一个超级快速的操作,基本上不需要任何时间:基本上,它会获取当前的毫秒经过值并将其递增,同时在以毫秒为键的映射中进行快速查找


你认为1毫秒的延迟会太快吗?这会使系统陷入困境吗?尝试使用这种超快计时器有什么危险吗?

可能。在当代计算机上,一毫秒内会发生很多事情,所以这取决于很多事情。您可能应该计算出可接受的最低速率,然后在1和该数字之间选择合理的值。这将每天执行86400000次左右。这对你想要实现的目标有意义吗


编辑:正如问题注释中的一些注释所示,如果您假设计时器总是以您提供的速率成功执行,那么这种方法可能存在根本性缺陷。无论利率是多少,你都不能做出这样的假设。很难说,因为细节很少,但我觉得你应该考虑使用队列而不是地图。

这取决于

问自己以下问题:

  • 我需要多久检查一次该值
  • 能接受多快的速度
  • 您愿意为此任务牺牲多少系统CPU时间
一毫秒可以是长的(高端游戏PC)或非常、非常短的(老一代智能手机),取决于您的CPU体系结构,您最终将填充多个
内核中的一个或唯一的内核,并计算时间差

至于您的数据结构:您可能需要一个像排序图这样的东西,其中包含开始作为键,持续时间作为值的一个字段。您将在少于您的时间内获取最近的密钥,并检查存储的标题是否仍然有效。。。或者类似的

“您认为1ms的延迟会太快吗?”-是的,它不能每毫秒启动一次任务(尤其是在加载时),您可以自己测试它(下面有一个小示例)

“这会使系统陷入困境吗?”-实际上不会太多(我指的是大部分CPU时间)。例如,如果您在循环中运行操作,并且不进行任何暂停,您将获得更多的负载。您的系统将在上下文切换上花费大量时间来启动任务,这是不可避免的开销,但如果您执行非常简单的任务,此开销将与您的有用工作负载相当

“尝试使用这个超快速计时器有什么危险吗?”-正如您在上面所写的“在以毫秒为键的地图中快速查找”您使用毫秒作为键,但不会每毫秒运行一次,因此如果计数被破坏,您的逻辑将被破坏

Timer timer = new Timer(true);
timer.scheduleAtFixedRate(timerTask, 0, 1);  // 1 = 1ms delay between each iteration

你需要多久做一次?是的,我认为这太快了,尽管这是基于直觉,而不是任何确凿的证据。你的目标是什么,为什么要读取计时器?一个潜在的问题是,某些平台的时间只能精确到几毫秒(例如,Windows以16毫秒的增量安排任务)。这取决于地图中的内容,而你完全不描述它!如果密钥的粒度为1毫秒,那么您基本上只能使用计时器的1毫秒粒度。需要1ms定时的危险是,有时候它可能无法成功地保持这个速率,尤其是在垃圾回收运行时。你考虑过使用while循环吗?你可以扔一根线;通常不建议这样做,但对于1ms的延迟,这可能是合理的。如果它落后了,您希望它表现如何?它是电影时间线的计时器,您点击播放,它启动计时器并更新时间线值。它将毫秒视为具有该毫秒标题的地图中的查找键。我的问题是我想知道我是否必须改变它,所以地图的关键不是精确的毫秒数,而是毫秒数。这样,我可以使用经过的时间作为查找。现在我必须使用经过的毫秒时间作为查找。。。但是如果每1ms执行一次计时器任务是错误的或有问题的,我可以改变这一点。标题是否与时间范围相关?如果是这样,地图可能不是最好的选择。如果这就是您正在做的,那么您需要做一些事情,比如创建一个范围内的类,即它有开始和结束时间以及标题。然后你把它们放在一个排序集或一个列表中,并保持排序。然后将计时器设置为所需的刷新率,当它启动时,对标题进行二进制搜索。JimmyJames,这可能会更好。我也会试试这个。它绝对是最慢的,需要每1秒运行一次,因为电影的新字幕可以在任何给定的秒出现,并且不会超过每秒一个。电影将在浏览器或媒体播放器中播放,并覆盖在电影顶部。我可以损失一些CPU时间,但我不想在电影开始的地方损失太多。所以你在电影中显示字幕。因此,基本上,任何超过1/30秒(或大约30毫秒)的速度都会浪费资源。考虑到观众需要在屏幕上阅读文本的时间,我想用250毫秒的支票你是相当安全的。酷。。。我会在一月份试一试。谢谢。我最后以1秒为周期,效果很好。我看了两部2小时长的电影,片头一次也没弄糟!!谢谢大家的帮助。@BrianTHannan谢谢反馈:-)
    static int inc = 0;
    public static void main(String[] args) throws InterruptedException {


        TimerTask timerTask = new TimerTask() {
            public void run() {                
                inc++;
            }
        };

        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(timerTask, 0, 1);        
        Thread.sleep(500000);
        timer.cancel();
        timer.purge();
        System.out.println(inc);
    }