在java web當中,servlet在運行階段,針對每個客戶端的請求,都會創建一個線程,該線程調用servlet的實例?

虹一法師


具體servlet的請求處理,這個是分配給線程池線程處理的,servlet容器都這樣實現,這個沒什麼問題。我主要來說說其它的。


線程池的作用

從其他人的回答看,都是太高看線程池本身的作用了。

線程池作為一種資源池(這裡的資源就是線程了)模型,最大的優點是重複利用已經創建的線程,避免線程的反覆創建和銷燬帶來的處理器和內存的消耗。而除此之外,它需要配合其它機制才能發揮更大的作用。

請求到達服務器後,如果線程池沒有可用線程,請求會進入隊列排隊,如果超過隊列最大閾值會被丟棄。重點來了,如果你的請求處理服務會有如數據庫調用/遠程服務調用的IO處理,而你用的阻塞模型,則這個線程在請求處理完成之前並不能返還到線程池供其它請求服務。這種長期佔用線程的行為,會嚴重限制請求的併發。線程的有效利用率太低,大部分時間都在阻塞中,這個和你有沒有線程池沒有關係。所以要在高併發的情況下保證性能,重點是你的服務內部的使用異步IO避免阻塞。這樣在你某個請求處於IO等待期間,當前線程可以返還給線程池繼續提供服務。

(補充)

下面有朋友提到了請求隊列,這裡簡單說下。

請求隊列是所有服務器程序都會考慮和設計的一個機制,這樣的機制實際上起緩衝層作用,避免服務器在請求過多時崩潰。以Tomcat為例,Connector中有下面幾個關鍵配置。

acceptCount就是允許未處理請求隊列的長度(backlog),默認是100,可以根據實際情況做調整。

更多的配置參見官方文檔。如果有時間,會寫一個Tomcat具體如何實現請求隊列及它的處理文章。

請求響應

更友好的體驗還要從客戶端出發來考慮,如果你能縮短請求的處理時間,客戶端體驗是極好的,比如成都訪問杭州阿里雲服務器,空載來回大概40ms的時間,如果你的服務處理控制在10ms以內,請求在50ms就可以返回,是不是很舒服?當然如果是靜態資源做CDN幾ms就可以完成。

要縮短請求響應時間,可以從兩方面入手:

1、將服務分解成多個可以並行處理的任務,這裡的任務一般都會包含一個異步IO調用,然後並行執行。

2、將不影響響應結果的子任務異步處理,提前返回響應。比如推送消息,日誌記錄等。考慮一些極端的情況:在雙11和秒殺場景,只有商品的庫存處理是最核心的,這個環節處理完就可以結束本次處理,像支付這種繁瑣的處理就可以延後,還有部分操作都可以放入異步隊列繼續處理。

將請求分解異步並行化後,實際上又會多出很多線程切換,這個時候線程池的作用就被放大了。

總結

僅僅有線程池而沒有異步並行框架的支撐,線程池其實只能發揮很小的作用,在高併發情況下它必不可少,但非最核心的那個東西。我們一般的Web應用都是IO密集型的,只要保證服務內的IO都異步化,線程池只需非常少量的線程就可以應對大量併發。


遷徙de麻雀


處理http請求的線程由JAVA WEB Server來管理。比如tomcat,jetty等。通常的作法是維護一個線程池,所有請求的執行都由這個線程池中的線程來完成,如果請求超過處理能力,就會發生等待甚至崩潰的情況,因此根據業務的訪問量合理的設置線程池大小是非常重要的。

以tomcat為例,下面的源代碼是tomcat處理http請求初始化的代碼。可以從源代碼中看出,tomcat會初始化一個ThreadPoolExecutor實例,而其中的參數可以在tomcat配置文件中進行配置。


希望可以解答題主的疑問。


java老菜鳥


不是每個調用都有新線程產生,這樣的話,併發量一上來不出幾分鐘就要掛了。主流的容器都有線程池,也就是最多同時可以接受多少連接,超過這個數的連接都要等待可用的線程才能處理。所以,在有空閒線程時不會創建新線程,就算沒空閒線程也得滿足條時才創建。


至亮時刻


應該不是這樣的原理

線程雖然異步,可以提升cpu的運行速率,但是線程過多也會造成cpu負荷過重,比如上下文切換,比如保存線程的堆棧信息等

而一般一個網站同時訪問量會達到幾百萬到上千萬,如果線程到達這個級別,服務器會卡死


前沿小子


java web其實是一種容器框架。實現線程安全的方法,簡單的說就是不要存取屬性。如果設計的不好,或者真是實際的需要,要在一個servlet實例中維持些狀態、連接器等信息時,你需要實現初始化、避免衝突的管理任務。


景151276607


不是的。不是創建,創建通常指給程序分配空間,在Java中所謂創建線程是指創建線程實例。而Web容器中負責請求處理的Servlt只是初次或實例實在不夠分配給引用的時候才創建實例(線程對象),否則通常情況下就直接啟動個線程(針對每個請求)來接受並分發請求(調用實例)。另外,一般沒有人會用它保管用戶的狀態,所以它的實例與訪問量(請求對象個數)絕不對稱。對稱的是線程,且分發掉請求就立刻熄滅。實例如同太陽,線程如同太陽的光線(不佔地方)。另外,像地球這麼大兒的地兒,一般一個太陽就夠了。一個站點慢或卡跟它沒關係。


分享到:


相關文章: