當前位置:
首頁 > 最新 > 簡析如何處理Servlet與多線程的關係

簡析如何處理Servlet與多線程的關係

Servlet與多線程的關係可以從以下四點來把握:

一,servlet容器如何同時處理多個請求。

Servlet採用多線程來處理多個請求同時訪問,Servelet容器維護了一個線程池來服務請求。

線程池實際上是等待執行代碼的一組線程叫做工作者線程(Worker Thread),Servlet容器使用一個調度線程來管理工作者線程(Dispatcher Thread)。

當容器收到一個訪問Servlet的請求,調度者線程從線程池中選出一個工作者線程,將請求傳遞給該線程,然後由該線程來執行Servlet的service方法。

當這個線程正在執行的時候,容器收到另外一個請求,調度者線程將從池中選出另外一個工作者線程來服務新的請求,容器並不關係這個請求是否訪問的是同一個Servlet還是另外一個Servlet。

當容器同時收到對同一Servlet的多個請求,那這個Servlet的service方法將在多線程中並發的執行。

二,Servlet容器默認採用單實例多線程的方式來處理請求,這樣減少產生Servlet實例的開銷,提升了對請求的響應時間。對於Tomcat可以在server.xml中通過元素設置線程池中線程的數目。

就實現來說:

調度者線程類所擔負的責任如其名字,該類的責任是調度線程,只需要利用自己的屬性完成自己的責任。所以該類是承擔了責任的,並且該類的責任又集中到唯一的單體對象中。

而其他對象又依賴於該特定對象所承擔的責任,我們就需要得到該特定對象。那該類就是一個單例模式的實現了。

三,如何開發線程安全的Servlet

1,變數的線程安全:這裡的變數指欄位和共享數據(如表單參數值)。

a,將 參數變數 本地化。多線程並不共享局部變數.所以我們要儘可能的在servlet中使用局部變數。

例如:String user = "";

user = request.getParameter("user");

b,使用同步塊Synchronized,防止可能非同步調用的代碼塊。這意味著線程需要排隊處理。

在使用同板塊的時候要儘可能的縮小同步代碼的範圍,不要直接在sevice方法和響應方法上使用同步,這樣會嚴重影響性能。

2,屬性的線程安全:ServletContext,HttpSession,ServletRequest對象中屬性

ServletContext:(線程是不安全的)

ServletContext是可以多線程同時讀/寫屬性的,線程是不安全的。要對屬性的讀寫進行同步處理或者進行深度Clone()。

所以在Servlet上下文中儘可能少量保存會被修改(寫)的數據,可以採取其他方式在多個Servlet中共享,比方我們可以使用單例模式來處理共享數據。

HttpSession:(線程是不安全的)

HttpSession對象在用戶會話期間存在,只能在處理屬於同一個Session的請求的線程中被訪問,因此Session對象的屬性訪問理論上是線程安全的。

當用戶打開多個同屬於一個進程的瀏覽器窗口,在這些窗口的訪問屬於同一個Session,會出現多次請求,需要多個工作線程來處理請求,可能造成同時多線程讀寫屬性。

這時我們需要對屬性的讀寫進行同步處理:使用同步塊Synchronized和使用讀/寫器來解決。

ServletRequest:(線程是安全的)

對於每一個請求,由一個工作線程來執行,都會創建有一個新的ServletRequest對象,所以ServletRequest對象只能在一個線程中被訪問。ServletRequest是線程安全的。

注意:ServletRequest對象在service方法的範圍內是有效的,不要試圖在service方法結束後仍然保存請求對象的引用。

3,使用同步的集合類:

使用Vector代替ArrayList,使用Hashtable代替HashMap。

4,不要在Servlet中創建自己的線程來完成某個功能。

Servlet本身就是多線程的,在Servlet中再創建線程,將導致執行情況複雜化,出現多線程安全問題。

5,在多個servlet中對外部對象(比方文件)進行修改操作一定要加鎖,做到互斥的訪問。

四,SingleThreadModel介面

javax.servlet.SingleThreadModel介面是一個標識介面,如果一個Servlet實現了這個介面,那Servlet容器將保證在一個時刻僅有一個線程可以在給定的servlet實例的service方法中執行。將其他所有請求進行排隊。

在這裡尚學堂陳老師要提醒同學們,伺服器可以使用多個實例來處理請求,代替單個實例的請求排隊帶來的效益問題。伺服器創建一個Servlet類的多個Servlet實例組成的實例池,對於每個請求分配Servlet實例進行響應處理,之後放回到實例池中等待下此請求。這樣就造成並發訪問的問題。

此時,局部變數(欄位)也是安全的,但對於全局變數和共享數據是不安全的,需要進行同步處理。而對於這樣多實例的情況SingleThreadModel介面並不能解決並發訪問問題。

SingleThreadModel介面在servlet規範中已經被廢棄了。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 九派新聞 的精彩文章:

梟龍科技創始人&CEO史曉剛獲評「2016中關村創業之星」
書籍推薦——尋路阿富汗
服務眾包平台是什麼意思?
梁家輝接戲不在乎片酬,誇高圓圓趙又廷夫妻演技好
趙麗穎成迪奧新寵,微博淪陷被舉報,這手段似曾相識

TAG:九派新聞 |