是否可以在spring boot/java中实现每个用户在不同时间动态调度一个任务

Posted

技术标签:

【中文标题】是否可以在spring boot/java中实现每个用户在不同时间动态调度一个任务【英文标题】:is it possible to achieve dynamic scheduling of a task for each user at different time in spring boot/java 【发布时间】:2021-08-03 01:08:23 【问题描述】:

我们有一个 REST API“/schedule”用于安排对 3rd 方 API 的调用。当一个用户登录并将他的调度器时间设置为 1 分钟的任务然后为每个用户设置它(使用方法名称为 scheduleAtFixedRate 的 shceduledExecutorService)

TaskUtils mytask1 = new TaskUtils(this);

            scheduledExecutorService = Executors.newScheduledThreadPool(1);

            futureTask = scheduledExecutorService.scheduleAtFixedRate(mytask1, 0, time, TimeUnit.MILLISECONDS);

但这不是实际要求。让我们通过一个例子来理解需求。 示例和要求:user1 登录并安排一个任务,时间差为 1 分钟。当 user2 登录时,他想将任务安排在 1 小时。所以,执行应该是不同用户在不同时间执行的定时任务。

【问题讨论】:

Surjeet,您在 cmets 中添加了许多要求/示例,以作为问题的一部分。你应该从一开始就明确目标。就目前而言,这个问题可以通过简单的“是的,这是可能的”来回答,这(由您的 cmets)似乎不是您的目标。 【参考方案1】:

将适当的时间传递给scheduleAtFixedRate 方法。

您的代码中已经有一个用于该目的的变量:time

您将毫秒指定为时间单位。使用Duration 类将分钟或小时转换为毫秒。

long time = Duration.ofMinutes( 1 ).toMillis() ;

或者从几小时到几毫秒。

long time = Duration.ofHours( 1 ).toMillis() ;

或使用标准ISO 8601 表示法指定的任意时间量。这是一个半小时。

long time = Duration.parse( "PT1H15M" ).toMillis() ;

在某处设置您的执行器服务。

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

在某处设置您的任务。

Task task = new TaskUtils(this);
…

编写一个为每个新用户调用的方法。

FutureTask scheduleTaskForUser ( Duration timeToWaitBetweenRunsForThisUser ) 
    ScheduledFuture scheduledFuture = scheduledExecutorService.scheduleAtFixedRate( task , 0 , timeToWaitBetweenRunsForThisUser.toMillis() , TimeUnit.MILLISECONDS );
    return scheduledFuture ; 

Alice 登录并说她想要 5 分钟的时间。

String input = … ;  // For example, "PT5M".
Duration d = Duration.parse( input ) ;
ScheduledFuture sf = scheduleTaskForUser( d ) ;
user.setScheduledFuture( sf ) ; 

当 Bob 登录时,为他的用户对象运行相同的代码。

稍后,Alice 想要更改时间量。在 Alice 的用户会话跟踪对象上调用另一个方法 rescheduleTaskForUser( Duration timeToWaitBetweenRunsForThisUser )。该方法为 Alice 访问存储的 ScheduledFuture 对象,取消该未来,再次安排任务,并返回一个新的 ScheduledFuture 对象以存储在 Alice 的用户会话跟踪对象中。

【讨论】:

好的,感谢您回答我的问题。我已经设法做到了。要求:User1通过1小时。用户 2 通过 2 小时。如何让调度程序在给定时间同时运行。 @SurjeetSinghRathore 您的代码已经做到了这一点。每次您为每个用户提交一个任务时,您都在传递该任务执行之间的时间。 先生您是对的,但同时 user1 无法更改他的任务执行时间。示例 user1 将执行时间设置为 1 小时。 user2 将其设置为 2 小时,当 user1 想要将其执行时间从 1 小时更改为 4 小时时会发生什么?他怎么能改变它?因为我们无法确定这是 user1 的预定时间。或者还有其他方法可以做到这一点。 @SurjeetSinghRathore (a) 您的问题没有询问更改计划任务的周期。 (b) 要更改周期,请捕获scheduleAtFixedRate 返回的ScheduledFuture 对象。取消该未来对象。然后再次安排您的任务,这次是不同的时间段。 我们可以唯一地识别未来的对象吗?还是我应该选择当前线程 id。正如您的评论给出了非常笼统的答案。我认为需要确定特定用户的未来对象才能结束该用户的计划任务。你对此有何看法。进一步的 cmets 将不胜感激

以上是关于是否可以在spring boot/java中实现每个用户在不同时间动态调度一个任务的主要内容,如果未能解决你的问题,请参考以下文章

Vertex中实现每顶点光照的镜面高光效果

Spring boot graphql-java 和订阅

如何在所有请求标头中传递授权令牌 - Spring Boot java

spring boot java项目上的/BOOT-INF/classes(没有这样的文件或目录)

可以使用域类在Spring Boot项目中实现UserDetails接口[关闭]

有一个免费的本地工具可以从 Spring Boot Java 应用程序的日志中创建见解,比如 Splunk?