Java 弹簧控制器在10秒后做一些工作

Java 弹簧控制器在10秒后做一些工作,java,spring,spring-mvc,Java,Spring,Spring Mvc,当用户发送请求时,请求中的信息将发送到远程网站。然后,我想调用一个API来检查请求是否成功发送。如果我立即调用它,它将不返回任何内容,因此应该在几秒钟后调用API 是否有任何方法可以让控制器休眠一段时间,或使任务在一段时间后自动执行?要休眠10秒,可以使用Thread.sleep(): 但是使用这种方法时要小心,它会阻塞您的线程,并且在超时过期之前不会让它处理其他用户请求。如果有许多这样的请求并行运行,则可能会导致线程池耗尽(最终导致请求超时) 要在10秒后执行某些任务,可以使用Timer.sc

当用户发送请求时,请求中的信息将发送到远程网站。然后,我想调用一个API来检查请求是否成功发送。如果我立即调用它,它将不返回任何内容,因此应该在几秒钟后调用API


是否有任何方法可以让控制器休眠一段时间,或使任务在一段时间后自动执行?

要休眠10秒,可以使用
Thread.sleep()

但是使用这种方法时要小心,它会阻塞您的线程,并且在超时过期之前不会让它处理其他用户请求。如果有许多这样的请求并行运行,则可能会导致线程池耗尽(最终导致请求超时)

要在10秒后执行某些任务,可以使用
Timer.schedule()

此调用将立即返回,稍后在单独的线程中执行检查。这种方法更加安全和可扩展

如果需要对延迟的任务进行更多控制,还可以使用
ScheduledExecutorService
。它将允许您定义将执行任务的线程池的大小、取消挂起的任务、从中获取结果等:

// Create a pool of threads to execute checks
private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(poolSize);

// In the request handler:
ScheduledFuture<?> future = scheduler.schedule(() -> {
    // Your code here
}, 10, TimeUnit.SECONDS);
//创建线程池以执行检查
专用最终计划执行器服务计划程序=
Executors.newScheduledThreadPool(池大小);
//在请求处理程序中:
ScheduledFuture future=scheduler.schedule(()->{
//你的代码在这里
},10,时间单位为秒);

请让我总结一下。如果您需要立即响应,您可以在服务/控制器方法上使用@Async注释(注意,您需要通过@enableSync配置注释来启用它)

@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}
接下来,autowire嵌入式spring调度程序:

@Autowired 
private TaskScheduler taskScheduler;
最后,计划执行:

taskScheduler.schedule(
    () -> {/*task code*/}, 
    new Date(OffsetDateTime.now().plusSeconds(10).toInstant().toEpochMilli())
);

关于spring中异步处理和调度的更多详细信息,您可能会发现

我考虑过这种方法,但我想知道它在spring Controller中是否正常。它会影响其他操作吗?
Thread.sleep()
是一个错误的选择,因为它会阻塞线程相当长的一段时间,不允许它处理其他请求。但如果您需要同步地将检查结果返回给用户,这是最简单的解决方案。否则,
Timer
更可取,因为它会立即返回,并允许您释放请求处理线程quickly.我尝试了
Timer
,但它抛出了
org.hibernate.hibernateeexception:无法获取当前线程的事务同步会话
。因为我对hibernate使用了
OpenSessionInView
,当请求完成时,数据库会话也关闭了。所以我无法操作数据库。嗨,我应该将任务计划放在哪里r、 计划工作?在哪个控制器方法中?在您想要的方法中。对于初始问题,如:public void acceptCall(Req Req){taskScheduler.schedule(()->{/*callback*/},新日期(OffsetDateTime.now().plusSeconds(10.toInstant().toepchmilli());}您研究过Spring
@Scheduled()
annotation?它可能在某种程度上适合您。
@Autowired 
private TaskScheduler taskScheduler;
taskScheduler.schedule(
    () -> {/*task code*/}, 
    new Date(OffsetDateTime.now().plusSeconds(10).toInstant().toEpochMilli())
);