JavaFX2的ScheduledService类

ScheduledService类位于javafx.concurrent包下面,是用来定时执行循环任务的。

ScheduledService继承自Service类,Service类会在成功执行任务后自动重新开始下一次执行,在一定的条件下及时执行失败了也会重新执行的。一个ScheduledService实例最初是READY状态,调用start()或者restart()方法后就变成SCHEDULED状态,然后持续该状态由delay指定的时长。

再进入RUNNING状态后ScheduledService就会开始执行它的Task,成功执行一次以后ScheduledService会变成SUCCEDED状态,然后变成READY,然后又开始SCHEDULED。在这个状态呆多久,取决于转变为RUNNING的时间、当前的时间和变量period值。简单点说,period定义了从一个Task开始到下一个的时长。如果执行完了period还是没到期,ScheduledService保持SCHEDULED状态等period耗完;反之,如果还没执行完period就到了,ScheduledService就立即开始RUNNINNG状态。

当在RUNNING的时候,ScheduledService抛异常了或者由于其他原因进入了FAILED状态,ScheduledService到底结束呢还是重新开始呢,取决于backoffStrategy, restartOnFailure 和 maximumFailureCount的值:

如果异常发生了而且restartonfailure是false,ScheduledService就进入FAILED停止了。只有调用restart方法才能重新运行;

如果异常发生了而restartonfailure是true,ScheduledService可能会自动重启。首先根据策略backoffstrategy的结果设置cumulativePeriod值,这样失败后会等待很久很久来重启;执行成功后cumulativePeriod就又变回period值;ScheduledService定义了几个静态策略,比如EXPONENTIAL_BACKOFF_STRATEGY 和 LOGARITHMIC_BACKOFF_STRATEGY,默认是后者。当maximumfailurecount达到后就和restartonfailure为false一样了。

如果执行过程中period或者delay改变了,它们将影响下一次执行。ScheduledService的典型应用是循环调用,比如以一定间隔ping一台主机:

 


 ScheduledService<Document> svc = new ScheduledService<Document>() {
     protected Task<Document> createTask() {
         return new Task<Document>() {
             protected Document call() {
                 // 连接主机
                 // 获取信息
                 // 转换成document
                 return document;
             }
         };
     }
 };
 svc.setPeriod(Duration.seconds(1));
 

这个任务每一秒执行一下。

不过这个类对于时间没什么太好的观念:不准确。一个非常忙的线程可能会引起比较严重的延迟。所以如果period或者delay的值很小可能不太准确,不过超过几百毫秒一般就相当可靠了。

ScheduledService的默认period和delay都是0,这样认为会立即一下一下地执行。想要取到执行的结果可以用lastValue属性。

 

你可能感兴趣的:(JavaFX2的ScheduledService类)