首页 > 解决方案 > Spring Boot Rest-Controller 限制多线程

问题描述

我希望我的 Rest Controller POST Endpoint 只允许一个线程执行该方法,并且每个其他线程都应该得到 429,直到第一个线程完成。

    @ResponseStatus(code = HttpStatus.CREATED)
    @PostMapping(value ="/myApp",consumes="application/json",produces="application/json")
    public Execution execute(@RequestBody ParameterDTO StartDateParameter)  
    {
        if(StartDateParameter.getStartDate()==null) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
        }else {
            if(Executer.isProcessAlive()) {
                throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS);
            }else {
                return Executer.execute(StartDateParameter);
            }       
        }
    }

当我发送多线程请求时,每个请求都会得到 201。所以我认为请求比被isAlive()检查的方法更早进入。如何将其更改为仅处理第一个请求并相互“阻止”?

标签: multithreadingspring-bootrestspring-restcontroller

解决方案


Spring中控制器的生命周期由容器管理,默认为单例,即启动时创建一个bean实例,多个线程可以使用。使其成为单线程的唯一方法是使用同步块或通过 Executor 服务处理请求调用。但这违背了使用 spring 框架的全部目的。

Spring 提供了其他方法来使您的代码线程安全。您可以使用 @Scope 注释来覆盖默认范围。由于您使用的是 RestController,因此您可以使用“请求”范围 (@Scope("request")),它会创建一个新实例来处理您的每个 http 请求。这样做将确保在任何给定时间只有 1 个线程将访问您的控制器代码。


推荐阅读