当前位置: 首页 > 知识库问答 >
问题:

JAVA ScheduledExecutorService在调用任务时仅运行一次

耿招
2023-03-14

当我把逻辑放在一个可运行的线程中时,它工作得很好,只是我不能与UI线程交互。所以我试图把所有的东西都放在一个类中,这个类扩展了Task,除了Task只执行一次之外,其他的都可以工作。没有错误,我从Task successed方法获得一条successed消息

我还尝试在call方法中使task return 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;
            }
        }
    }
}

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

谢谢!

共有1个答案

齐成和
2023-03-14

ScheduledExecutorService将简单地将您提供的任务视为可运行的任务,并尝试在每次运行时重用相同的任务实例,这在文档中是明确禁止的。

使用执行服务代替:

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


}
 类似资料:
  • 问题内容: 是否可以在确切指定的时间仅安排一次Spring服务方法?例如,当前时间是下午2点,但是当我按下操作按钮时,我希望我的服务方法从晚上8点开始。我熟悉@Scheduled批注,并且不确定如何编写cron表达式以使其不定期运行。这一次,每天晚上8点触发。 有什么建议么? 问题答案: 你可以使用Spring的TaskScheduler的实现之一。我在下面提供了一个示例,该示例不需要太多的配置(

  • 问题内容: 我正在使用Camel&Spring进行Java项目。在Spring完成其工作并且Camel完成所有路径的构建之后,我们想在单例bean上触发一个initialize方法。 我们无法在类创建时调用该方法,因为它具有从@Component spring批注中拾取的与其他类的动态链接,并且我们不知道何时/是否已加载这些类,而尚未真正将init方法作为a的一部分运行构造函数。 我如何才能在Ca

  • 问题内容: 是否可以在确切指定的时间仅安排一次Spring服务方法?例如,当前时间是下午2点,但是当我按下操作按钮时,我希望我的服务方法从晚上8点开始。我熟悉@Scheduled批注,但不确定如何编写cron表达式以使其不定期运行。这一次,每天晚上8点触发。 有什么建议? 问题答案: 您可以使用Spring的TaskScheduler的实现之一。我在下面提供了一个示例,该示例不需要太多配置(包装了

  • 我正在从事一个spring boot项目,以自动化与gradle的集成测试。我最近开始在一家新企业工作,我的同事们按如下方式运行集成测试:在构建中。gradle文件有一个集成测试任务 启动任务后,应用程序开始在指定端口运行,然后打开postman,导入集合并运行测试。 我的工作是找到一种方法来跳过额外的点击,即自动运行邮递员集合。第一个想法是使用postman-run gradle插件,但由于企业

  • 问题内容: 我想将我的python软件包设为“ pip installable”。问题在于,程序包具有必须来自用户的初始Shell脚本(例如)的Shell脚本。 但是在安装之后,用户并不完全知道脚本的去向(大概是,但是我们不能保证)。当然,用户可以运行并手动编辑其初始化脚本。 但我想使这一步骤自动化。我可以创建一个新的distutils命令,但不调用它。而且我可以扩展,但是安装会通过pip中断(尽

  • 是否可以只在指定的时间安排一次Spring服务方法?例如,当前时间是下午2点,但当我点击action按钮时,我希望我的服务方法在晚上8点开始。我很熟悉@Schedured注释,我不确定如何编写不定期运行的cron表达式。这个每天晚上8点触发。 有什么建议吗?