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屬性。