JAVA ScheduledExecutorService在调用Task< V>时仅运行一次. [英] JAVA ScheduledExecutorService only runs once when calling a Task<V>

查看:75
本文介绍了JAVA ScheduledExecutorService在调用Task< V>时仅运行一次.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我将逻辑包含在Runnable中时,它可以正常工作,但是无法与UI线程进行交互.因此,我试图将所有内容放入扩展Task的类中,并且该类可以正常工作,只是该任务仅执行一次.没有错误,我从Task成功方法中获得了成功消息.

When I had my logic inside a Runnable it worked fine except I could not interact with the UI Thread. So I am trying to put everything inside a class that extends Task and it works Except the task is only executed once. No errors and I get a succeeded message form the Task succeeded method.

我也曾尝试在call方法中使任务返回布尔值true,但这没有帮助.

I have also tried making the task return Boolean true in the call method but that did not help.

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中,以尝试提供自包含的代码.

Please note that this code actually exists inside a controller but I put it in Main here to try and provide self contained code.

谢谢!

推荐答案

ScheduledExecutorService将简单地将您提供的任务视为Runnable,并尝试在每次运行时重用同一任务实例,这显然是在文档中被禁止.

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.

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


}

这篇关于JAVA ScheduledExecutorService在调用Task&lt; V&gt;时仅运行一次.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆