爲什麼寫?
今天看了Spring實戰第五版,裏邊有句話如下:
傳統的基於Servlet的Web框架,如Spring MVC,在本質上都是阻塞和多線程的,每個連接都會使用一個線程。在請求處理的時候,會在線程池中拉取一個工作者(worker)線程來對請求進行處理。(讀到這裏沒啥疑問,但是接下來說的我有點疑惑)
同時,請求線程是阻塞的,直到工作者線程提示它已經完成爲止。
我就在想SpringBoot默認內置的Tomcat應該是Nio,請求線程不應該是阻塞的,應該是同步非阻塞的,於是回顧下請求過程。
Tomcat中的管道
SpringBoot啓動tomcat過程
線程池創建,說明見流程圖:
public void createExecutor() {
internalExecutor = true;
TaskQueue taskqueue = new TaskQueue();
TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
taskqueue.setParent( (ThreadPoolExecutor) executor);
}
當然最主要的我是想看看啓動的worker是怎樣的,這個過程涉及到三個類:
Acceptor:接受來自服務器的下一個傳入連接Socket,socket=endpoint.serverSocketAccept();
NioEndpoint:NIO定製的線程池,提供以下服務:Socket acceptor thread、Socket poller thread、Worker threads pool
Poller:向輪詢器添加套接字的後臺檢查線程對觸發事件進行輪詢,並將關聯的套接字傳遞給事件發生時的適當處理器。