Spring是否在休息控制器中为每个请求创建新线程?

时间:2017-12-22 08:37:25

标签: spring spring-mvc

我想学习非阻塞REST,但首先我写了阻塞控制器进行比较。令我惊讶的是,Spring并没有阻止传入的请求。

简单阻止服务:

@Service
public class BlockingService {

    public String blocking() {
        try {
            Thread.sleep(10000L);
        } catch (InterruptedException ign) {}
        return "Blocking response";
    }
}

简单的REST控制器:

@Slf4j
@RestController
public class BlockingRestController {

    private final BlockingService blockingService;

    @Autowired
    public BlockingRestController(BlockingService blockingService) {
        this.blockingService = blockingService;
    }

    @GetMapping("blocking")
    public String blocking() {
        log.info("Starting blocking request processing...");
        return blockingService.blocking();
    }
}

而且我在想,当我使用来自4个分离的罪犯的curl发送4个请求时,我得到:

1. Starting blocking request processing... (console where spring is running)
2. (4 terminals waiting)
3. "Blocking response" (in 1st terminal)
4. Starting blocking request processing... (console where spring is running)
5. (3 terminals waiting)
6. "Blocking response" (in 2nd terminal)
And so on...

但令我惊讶的是我得到了:

1. Starting blocking request processing... (console where spring is running)
2. Starting blocking request processing... (console where spring is running)
3. Starting blocking request processing... (console where spring is running)
4. Starting blocking request processing... (console where spring is running)
5. "Blocking response" (in 1st terminal)
6. "Blocking response" (in 2nd terminal)
7. "Blocking response" (in 3rd terminal)
8. "Blocking response" (in 4th terminal)

为什么第一个请求不会阻止处理请求?然而,我不创建新线程,我不处理任何异步?

为什么我问这个问题?因为我想学习使用DeferredResult但现在我没有看到需要。

2 个答案:

答案 0 :(得分:10)

它阻止一个线程的阻塞:servlet容器从线程池中取出的线程(Tomcat,Jetty等, not Spring)来处理您的请求。幸运的是,许多线程同时用于处理请求,否则任何Java Web应用程序的性能都会非常惊人。

如果你有,请说,500个并发请求都需要1分钟才能完成,并且线程池有300个线程,然后200个请求将排队等待其中一个线程变为可用。

答案 1 :(得分:0)

从蔚来就绝对没有!!! Spring Web 运行在一个 web 容器 Tomcat 或 Netty 中,创建线程是 tomcat 或 Netty 的工作,而不是 spring mvc 或 spring webflux。 如果在 BIO 模型中使用 tomcat,它肯定是每个请求的新线程。 Netty当然是NIO,tomcat支持NIO和APR,都是非阻塞的, spring boot webmvc tomcat默认是NIO,nio以后不用担心创建多线程。

Tomcat 8 NIO,how it works?