Javafx 使用时间线安排是否正确

Javafx 使用时间线安排是否正确,javafx,timer,Javafx,Timer,我发现了很多建议,可以使用Timeline和KeyFrame.onFinished在JavaFX中安排任务。但是AnimationTimerdoc说,它的handle方法每秒调用60次 文档中不清楚,但似乎Timeline在内部使用了AnimationTimer。这是否意味着用于调度的时间线解决方案强制采用CPU密集型轮询模式?如果JavaFX确实是这样工作的,那么还推荐使用哪些其他调度方法?您可以使用 JavaFX中调度的建议使用规则 根据工作原理(见下文),可以推导出一些基本规则: 要计划修

我发现了很多建议,可以使用
Timeline
KeyFrame.onFinished
在JavaFX中安排任务。但是
AnimationTimer
doc说,它的
handle
方法每秒调用60次

文档中不清楚,但似乎
Timeline
在内部使用了
AnimationTimer
。这是否意味着用于调度的时间线解决方案强制采用CPU密集型轮询模式?如果JavaFX确实是这样工作的,那么还推荐使用哪些其他调度方法?

您可以使用


JavaFX中调度的建议使用规则

根据工作原理(见下文),可以推导出一些基本规则:

  • 要计划修改场景图属性的快速操作时,请使用时间线

  • 如果要执行以下任一操作,请不要使用时间线:

  • 执行本身耗时的操作(例如,给定计划活动的工作时间超过1/30秒)
  • 执行与场景图完全无关的工作
  • 以大于脉冲(1/60秒)的分辨率进行实时调度
  • 使用传统的java.util.concurrent机制或第三方库控制调度
  • 在自己的线程上运行计划任务
  • 另外,对于在固定延迟后更新场景图的一次性执行,我喜欢使用

    对特定问题和顾虑的回答

    文档中不清楚,但似乎Timeline内部使用了AnimationTimer

    不,不在内部使用。然而,时间线仍然是基于脉冲的,并且将接收更新时间线当前状态的代码,该代码将在每个脉冲上调用(通常每秒60次)。要了解脉冲是什么,请阅读下面的背景部分

    这是否意味着用于调度的时间线解决方案强制采用CPU密集型轮询模式

    是的,有一些开销,但它可能是最小的,可以忽略不计。JavaFX系统将在每个脉冲上运行一些工作,不管您是否自己创建任何时间线。除非您正在为对象设置大量动画或在每个脉冲上做大量工作,否则处理每个脉冲的时间将完全微不足道,因为在每个脉冲上要做的工作非常少

    如果JavaFX实际上就是这样工作的,那么推荐使用哪些其他调度方法

    有许多替代时间表的方法:

  • 使用诸如任务或服务等设施,特别是。
    • 如果您希望向JavaFXUI提供反馈(如进度、消息更新和返回值),这是很好的
  • 使用设备。
    • 如果进度和消息传递不需要javafx.concurrent的附加功能,或者希望java.util.concurrent工具提供附加控制,那么这很好
    • 如果您使用它,您仍然可以通过调用
  • 使用一个。
    • 比java.util.concurrent更简单的API,没有用于JavaFX反馈的直接接口,不过您也可以使用Platform.runLater()实现这一点
  • 使用第三方调度系统(例如):
    • 比其他解决方案更复杂,但也更灵活,尽管它添加了一个依赖库,并且如果要修改场景图形元素,则需要Platform.runLater
  • 如果您使用的不是时间线,您需要注意:

  • 如果要从非JavaFX应用程序线程修改场景图上的任何内容,请调用Platform.runLater
  • 您不会太频繁地调用Platform.runLater,以使JavaFX应用程序线程过载(例如,通过)
  • 背景信息

    时间轴操作

    例如,假设您有一个持续时间为1秒的时间线。内部时间线仍将在每个脉冲中更新。这是必需的,因为时间线不仅仅是计划程序,它还有其他属性和任务。例如,时间轴有一个属性。每次脉冲都会更新currentTime,以便它始终准确地反映当前时间。类似地,带有时间线的内部逻辑将检查是否有任何与时间线关联的数据,并根据其关联的数据更新每个脉冲上的值。内部逻辑将检查每个脉冲,查看时间轴是否完成,以调用onFinished处理程序。它还将评估当前时间与每个关键帧的持续时间,如果存在匹配,则为关键帧触发适当的动作事件

    因此,时间轴就像一个调度器,它可以在特定的时间执行关键帧,但它不仅仅是一个调度器,因为它还保持它的当前时间、当前状态以及不断改变相关键值的能力。此外,您可以改变时间线的速率、方向和周期数,也可以暂停时间线,然后恢复时间线,这也不同于传统的计划程序

    时间线的一个方面是,因为它基于JavaFX系统中脉冲的回调;一切都在JavaFX应用程序线程上运行。因此,当您使用时间线(甚至1000个)时,不会产生额外的线程,因此从这个角度来看,它是轻量级的。时间线调用的所有逻辑也发生在JavaFX应用程序线程上。因为一切都在JavaFX应用程序线程上运行,这使得时间线对于操作活动JavaFX场景图的元素和属性来说很好(此类操作必须在JavaFX应用程序线程上执行)。然而,如果你想做一个l,时间线将是一个糟糕的选择
    final Runnable runnable = new Runnable() {
        public void run() {
            //Code goes here
        }
    }
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    executor.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);