[英]JAVA ScheduledExecutorService only runs once when calling a Task<V>
When I had my logic inside a Runnable it worked fine except I could not interact with the UI Thread. 当我将逻辑包含在Runnable中时,它可以正常工作,除了无法与UI线程交互。 So I am trying to put everything inside a class that extends Task and it works Except the task is only executed once. 因此,我试图将所有内容放入扩展Task的类中,并且该类可以正常工作,只是任务仅执行一次。 No errors and I get a succeeded message form the Task succeeded method. 没有错误,我从任务成功方法中收到一条成功消息。
I have also tried making the task return Boolean true in the call method but that did not help. 我也尝试在call方法中使任务返回Boolean true,但这没有帮助。
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception{
SyncTask syncTask = new SyncTask();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(syncTask, 0, 10, TimeUnit.SECONDS);
Label syncEngineLabel = centralController.getScheduleTabMessageLabel();
syncEngineLabel.textProperty().bind(syncTask.messageProperty());
}
class SyncTask extends Task<Void>{
private Schedule schedule = null;
public SyncTask() {}
@Override
protected Void call() throws Exception {
System.out.println("we are in the task...");
if (getScheduleFromApi()){
updateMessage("New Schedule Retrieved...");
}
return null;
}
@Override protected void succeeded() {
super.succeeded();
System.out.println("succeeded");
}
@Override protected void cancelled() {
super.cancelled();
System.out.println("cancelled");
}
@Override protected void failed() {
super.failed();
System.out.println("failed");
}
private Boolean getScheduleFromApi(){
Gson gson = new GsonBuilder().serializeNulls().create();
ApiGet api = new ApiGet("schedule/get-schedule-by-room", parameters);
api.sendRequest();
if (api.isSuccess()){
schedule = gson.fromJson(api.response(), Schedule.class);
if (schedule.getStatus().equals("200")){
return true;
}
else{
updateMessage(schedule.getMsg());
return false;
}
}
else {
updateMessage("Failed to process API call to ASI Server.");
return false;
}
}
}
}
Please note that this code actually exists inside a controller but I put it in Main here to try and provide self contained code. 请注意,该代码实际上存在于控制器中,但是我将其放在Main中以尝试提供自包含的代码。
Thanks! 谢谢!
The ScheduledExecutorService
will simply treat the task you provide as a Runnable
, and try to reuse the same task instance every time it runs, which is explicitly forbidden in the documentation . ScheduledExecutorService
会将您提供的任务简单地视为Runnable
,并在每次运行时尝试重用同一任务实例,这在文档中已明确禁止。
Use a ScheduledService
instead: 改用ScheduledService
:
@Override
public void start(Stage primaryStage) throws Exception{
ScheduledService<Void> scheduledService = new ScheduledService<Void>() {
@Override
protected Task<Void> createTask() {
return new SyncTask();
}
};
scheduledService.setPeriod(Duration.seconds(10));
scheduledService.start();
Label syncEngineLabel = centralController.getScheduleTabMessageLabel();
scheduledService.stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.RUNNING) {
syncEngineLabel.setText("Sync in progress");
} else if (newState == Worker.State.FAILED) {
syncEngineLabel.setText("Sync error");
} else {
syncEngineLabel.setText("Sync complete");
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.