JAVA ScheduledExecutorService仅在调用Task <v>时运行一次

时间:2017-10-25 17:41:52

标签: java javafx-8 scheduled-tasks

当我在Runnable中使用我的逻辑时,它工作得很好,除了我无法与UI线程交互。因此,我试图将所有内容放在一个扩展Task的类中,并且它可以工作除了任务只执行一次。没有错误,我从任务成功的方法中获得了成功的消息。

我也尝试在调用方法中使任务返回布尔值为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;
            }
        }
    }
}

请注意,此代码实际存在于控制器内部,但我将其放在Main中以尝试提供自包含代码。

谢谢!

1 个答案:

答案 0 :(得分:2)

ScheduledExecutorService只会将您提供的任务视为Runnable,并尝试在每次运行时重复使用相同的任务实例,这在documentation中明确禁止。< / p>

改为使用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");
            }
    });


}