開發執行緒安全的Servlet

2021-07-15 00:07:29 字數 1922 閱讀 2111

servlet規範定義,在預設情況下(servlet不是在分布式的環境部署),servlet容器對宣告的每乙個servlet,只建立乙個例項。若有多個客戶請求同時訪問這個servlet,servlet容器將採用多執行緒,servlet容器維護了乙個執行緒池來服務請求。執行緒池實際上是等待執行**的一組執行緒,這些執行緒叫做工作者執行緒(worker thread)。servlet容器使用乙個排程者執行緒(dispatcher thread)來管理工作者執行緒。當容器接收到乙個訪問servlet的請求,排程者執行緒從從執行緒池中選取乙個工作者執行緒,將請求傳遞給該執行緒,然後由這個執行緒執行servlet的service()方法。

當這個執行緒正在執行的時候,容器收到了另外乙個請求,排程者執行緒將從池中選取另乙個執行緒來服務新的請求。servlet容器並不關心這第二個請求是訪問同乙個servlet還是另乙個servlet。因此,如果容器同事收到訪問同乙個servlet的多個請求,那麼這個servlet的service()方法將在多個執行緒中併發的執行。

由於servlet容器採用了單例項多執行緒的方式,最大限度地減少了產生servlet例項的開銷,顯著地提公升了對請求的響應時間。對於tomcat,可以在server.xml檔案中通過元素設定執行緒池中線程的數目。

1 變數的執行緒安全

執行緒對自己棧中的本地變數的改變不會影響其他執行緒的本地變數的拷貝,因此,在請求處理過程中,user的值將不會被別的執行緒所改變,在servlet的開發中,本地變數總是執行緒安全的。

第二種方法是同步doget()方法 synchronized 這意味著訪問同乙個servlet的請求將排隊,乙個執行緒處理完請求後,才能執行另乙個執行緒,這將嚴重影響效能。

對於servlet中的類變數(靜態變數),因為他們在所有屬於該類的例項中共享,所以也不是執行緒安全的。類變數在servlet中常被用於儲存唯讀的或常量的資料,例如儲存jdbc驅動程式類名,連線url。

2 屬性的執行緒安全

在servlet中,可以訪問儲存在servletcontext,httpsession和servletrequest物件中的屬性,這三種物件都提供了getattribute()和setattribute()方法用於讀取和設定屬性。

servletcontext物件可以被web應用程式中所有的servlet訪問,多個執行緒可以同時在servlet上下文中設定或者讀取屬性,這將導致儲存資料的不一致。

httpsession物件在使用者會話期間存活,他不像servletcontext物件,可以在web應用程式的所有執行緒中被訪問,httpsession物件只能在處理屬於同乙個session的請求的執行緒中被訪問。

servlet容器對它所接收到的每乙個請求,都建立乙個新的servletrequest物件,所以servletrequest物件只在乙個執行緒中被訪問。因為只有乙個執行緒服務請求,所以請求物件的屬性訪問是執行緒安全的。要注意的是,servletrequest物件是作為引數傳進servlet的service()方法中的,,在service()方法的範圍內,該請求物件是有效的不要試圖在service()方法結束後,仍然儲存請求物件的引用,如果那樣的話,請求物件的行為將不可預料。

提示:在多執行緒的環境中使用集合類物件時,應該使用同步的集合類,例如vector代替arraylist,用hashtable代替hashmap。

在開發servlet時,要注意執行緒安全的問題:乙個是變數的執行緒安全,本地變數總是執行緒安全的,例項變數和類變數不是執行緒安全的;另乙個是屬性的執行緒安全,請求物件的屬性訪問是執行緒安全的,而session物件和上下文物件的屬性訪問不是執行緒安全的。

建議:▶盡可能地在servlet中使用本地變數

▶應該使用唯讀的例項變數和靜態變數

▶不要在servlet中建立自己的執行緒

▶修改共享物件時,一定要使用同步,盡可能地縮小同步**的範圍,不要直接在service()方法或do***()方法上進行同步,以免影響效能。

▶如果在多個不同的servlet中,要對外部物件(例如,檔案)進行修改操作,一定要加鎖,做到互斥的訪問。

servlet執行緒安全

很多情況下,可能會有很多併發的請求,為了提高執行效率,節省記憶體資源,容器採用thread pool.一般情況下容器只對每個servlet生成乙個例項,讓他服務於說有的請求,對於客戶端同時請求乙個servlet,他們是被併發的處理的,並不是等上乙個請求處理完成再處理下乙個。如果兩個請求同時到達,那麼...

Servlet 執行緒安全

普通類的靜態屬性,當被多個執行緒訪問時,就有執行緒安全問題 servlet也一樣 當多個客戶端併發訪問同乙個servlet時,web伺服器會為每乙個客戶端的訪問請求建立乙個執行緒,並在這個執行緒上呼叫servlet的service方法,因此service方法內如果訪問了同乙個資源的話,就有可能引發執...

設計執行緒安全的Servlet

設計執行緒安全的servlet 例項變數和類變數不正確的使用是造成servlet執行緒不安全的主要原因。1 實現 singlethreadmodel 介面 2 同步對共享資料的操作 使用synchronized 關鍵字能保證一次只有乙個執行緒可以訪問被保護的區段,在本 中的servlet可以通過同步...