服務器的實現不止有這兩種方式。數據庫
先談談題主說的這兩種服務器模型:apache
一、收到一個請求就處理,這個時候就不能處理新的請求,這種爲阻塞
這個是單線程模型,沒法併發,一個請求沒處理完服務器就會阻塞,不會處理下一個請求。通常的服務器不會使用這種方式實現。編程
二、收到一個請求就新開一個線程去處理任務,主線程返回,繼續處理下一個任務,這種爲非阻塞
首先糾正一個錯誤,這並非非阻塞,它也是阻塞的。相對第一個模型來講,它解決了主線程阻塞的問題,有了必定程度的併發量,可是在每一個新開的線程中仍是阻塞的。若是100我的同時訪問,將會開100個線程,那1000我的,10000我的呢?頻繁開關線程很消耗資源,這樣實現的服務器性能依然不高。服務器
除了上面的兩種方式,接下來的說說其餘更好的方式:網絡
三、相似2的模型,可是不是每次收到請求就開一個新的線程,而是使用線程池
若是不瞭解線程池,你可能會了解數據庫鏈接池,因爲頻繁建立、關閉數據庫鏈接會消耗資源,因此會用數據庫鏈接池來保存必定數量的鏈接,若是須要就從鏈接池裏取鏈接,不須要則放回鏈接池,不在頻繁建立。線程池也是同樣的道理,線程池管理多線程,性能比頻繁建立線程高得多。這種方式實現的服務器性能會比2高。不過,它依然是阻塞的。線程池的線程數量一般有限制的,若是全部線程都被阻塞(例如網速慢,或者被人惡意佔用鏈接),那麼接下來的請求將會排隊等待。多線程
四、基於Java NIO實現的服務器模型
上面說到的幾種模型,都是基於BIO(阻塞IO)。而NIO則是非阻塞IO,它是基於IO多路複用技術(例如Reactor模式)實現,只須要一個線程或者少許線程,就能夠處理大量請求。從性能上來講NIO實現的服務器併發性通常大於BIO,因此能夠實現高性能的服務器。若是感興趣,能夠學習一些基於NIO的網絡編程框架,例如Netty、MINA。併發
最後,回答一下題主說到的Tomcat。Tomcat運行能夠選擇BIO或者NIO模型,原理分別對應上面的3和4兩種方式。Tomcat默認是BIO方式運行,若是想要換成NIO,能夠配置server.xml:框架
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" .../>
從性能上考慮建議使用NIO。性能