运行计划任务链

时间:2015-06-04 16:55:36

标签: java multithreading javafx scheduled-tasks

  1. 我需要在执行上一个任务后逐个执行预定任务,并有不同的延迟。 例。有一个任务列表和延迟列表。

    toRun = {task1, task2, ..., taskn}
    delays = {100, 9, 22, ..., 1000}
    
  2. 现在我需要在task1到9ms之后运行task1 throgh 100ms,task2,在task2到22ms之后运行task3,等等。

    1. 我正在使用javafx。任务可以使用一些UI更新方法,例如更改节点位置。这迫使我使用 Platform.runLater()方法,因为如果我不这样做,那么我将有一个异常“Not on FX application thread”。据我所知,这个方法在未定义的时间后运行 Runnable 对象。根据时间的不同,我有两种方式。

      2.1如果呼叫时间<继续使用 Platform.runLater()方法。 1-2MS。

      2.2找到另一种解决方案,我还没有。

    2. 关于实际任务。我记录用户操作,如鼠标移动,鼠标单击和一些应用程序事件。之后我需要重播这些动作。因此,我使用 ScheduledExecutorService.schedule()执行每个操作,并在每个操作任务内部将下一个任务放入调度程序。每次出现问题,或者感觉不够稳定。

      我认为这里的代码不会那么有用,因为它有两个杂乱而且有点大,可以快速搞清楚

1 个答案:

答案 0 :(得分:1)

假设实际任务本身(不包括延迟)不需要花费很长时间(因此它们可能在FX应用程序线程上完全执行),您可以使用Timeline,如下所示:

Runnable[] tasks = { /* task1, task2, ..., taskN */ } ; // N elements
int[] delays = { 100, 9, 22, ..., 1000 }; // N-1 elements (delay after task1, ..., task(N-1)

KeyFrame[] frames = new KeyFrame[tasks.length] ;
int cumulativeMillis = 0 ;
for (int i = 0; i < tasks.length; i++) {
    frames[i] = new KeyFrame(Duration.millis(cumulativeMillis), event -> tasks[i].run());
    if (i < delays.length) {
        cumulativeMillis += delays[i] ;
    }
}
Timeline timeline = new Timeline(frames);
timeline.play();

使用这种方法,无需担心多线程:Timeline负责处理线程问题。每个任务都在FX应用程序线程上执行(但它们之间的暂停不会阻止该线程)。