posts - 14,  comments - 37,  trackbacks - 0
          簡單的說, servlet絕對(duì)不是線程安全的, 所以, 盡量比聲明servlet的屬性, 雖然可以得到解決辦法, 但是性能上都不好的.
          如下的文字摘自好多的網(wǎng)站了.
          鏈接列表:
          http://www.itisedu.com/phrase/200603091005185.html
          http://developer.51cto.com/art/200610/32858.htm
          http://www.it-accp.com/news_read.asp?id=75&hangclassname=%E5%AD%A6%E4%B9%A0%E5%9B%AD%E5%9C%B0
          http://blog.csdn.net/Explorering/archive/2006/10/11/1330744.aspx

          Servlet生命周期

            裝載Servlet。這項(xiàng)操作一般是動(dòng)態(tài)執(zhí)行的。然而,Server通常會(huì)提供一個(gè)管理的選項(xiàng),用于在Server啟動(dòng)時(shí)強(qiáng)制裝載和初始化特定的Servlet。

            Server創(chuàng)建一個(gè)Servlet的實(shí)例

            Server調(diào)用Servlet的init()方法

            一個(gè)客戶端的請(qǐng)求到達(dá)Server

            Server創(chuàng)建一個(gè)請(qǐng)求對(duì)象

            Server創(chuàng)建一個(gè)響應(yīng)對(duì)象

            Server激活Servlet的service()方法,傳遞請(qǐng)求和響應(yīng)對(duì)象作為參數(shù)

            service()方法獲得關(guān)于請(qǐng)求對(duì)象的信息,處理請(qǐng)求,訪問其他資源,獲得需要的信息

            service()方法使用響應(yīng)對(duì)象的方法,將響應(yīng)傳回Server,最終到達(dá)客戶端。service()方法可能激活其它方法以處理請(qǐng)求,如doGet()或doPost()或程序員自己開發(fā)的新的方法

            對(duì)于更多的客戶端請(qǐng)求,Server創(chuàng)建新的請(qǐng)求和響應(yīng)對(duì)象,仍然激活此Servlet的 service()方法,將這兩個(gè)對(duì)象作為參數(shù)傳遞給它。如此重復(fù)以上的循環(huán),但無需再次調(diào)用init()方法。一般Servlet只初始化一次 ,當(dāng)Server不再需要Servlet時(shí)(一般當(dāng)Server關(guān)閉時(shí)),Server調(diào)用Servlet的Destroy()方法。

           

          Servlet體系結(jié)構(gòu)是建立在Java多線程機(jī)制之上的,它的生命周期是由Web容器負(fù)責(zé)的。當(dāng)客戶端第一次請(qǐng)求某個(gè)Servlet時(shí), Servlet容器將會(huì)根據(jù)web.xml配置文件實(shí)例化這個(gè)Servlet類。當(dāng)有新的客戶端請(qǐng)求該Servlet時(shí),一般不會(huì)再實(shí)例化該 Servlet類,也就是有多個(gè)線程在使用這個(gè)實(shí)例。 這樣,當(dāng)兩個(gè)或多個(gè)線程同時(shí)訪問同一個(gè)Servlet時(shí),可能會(huì)發(fā)生多個(gè)線程同時(shí)訪問同一資源的情況,數(shù)據(jù)可能會(huì)變得不一致。所以在用Servlet構(gòu)建的Web應(yīng)用時(shí)如果不注意線程安全的問題,會(huì)使所寫的Servlet程序有難以發(fā)現(xiàn)的錯(cuò)誤。

          實(shí)例變量不正確的使用是造成Servlet線程不安全的主要原因。下面針對(duì)該問題給出了三種解決方案并對(duì)方案的選取給出了一些參考性的建議。

            1、實(shí)現(xiàn) SingleThreadModel 接口

             該接口指定了系統(tǒng)如何處理對(duì)同一個(gè)Servlet的調(diào)用。如果一個(gè)Servlet被這個(gè)接口指定,那么在這個(gè)Servlet中的service方法將不 會(huì)有兩個(gè)線程被同時(shí)執(zhí)行,當(dāng)然也就不存在線程安全的問題。這種方法只要將前面的Concurrent Test類的類頭定義更改為:

          Public class Concurrent Test extends HttpServlet implements SingleThreadModel {
               …………
          }

            2、同步對(duì)共享數(shù)據(jù)的操作

            使用synchronized 關(guān)鍵字能保證一次只有一個(gè)線程可以訪問被保護(hù)的區(qū)段,在本論文中的Servlet可以通過同步塊操作來保證線程的安全。同步后的代碼如下:

          …………
          Public class Concurrent Test extends HttpServlet { …………
          Username = request.getParameter ("username");
          Synchronized (this){
          Output = response.getWriter ();
          Try {
          Thread. Sleep (5000);
          } Catch (Interrupted Exception e){}
          output.println("用戶名:"+Username+"
          ");
          }
          }
          }

            3、避免使用實(shí)例變量

            本實(shí)例中的線程安全問題是由實(shí)例變量造成的,只要在Servlet里面的任何方法里面都不使用實(shí)例變量,那么該Servlet就是線程安全的。

            修正上面的Servlet代碼,將實(shí)例變量改為局部變量實(shí)現(xiàn)同樣的功能,代碼如下:

          ……
          Public class Concurrent Test extends HttpServlet {public void service (HttpServletRequest request, HttpServletResponse
          Response) throws ServletException, IOException {
          Print Writer output;
          String username;
          Response.setContentType ("text/html; charset=gb2312");
          ……
          }
          }

             對(duì)上面的三種方法進(jìn)行測試,可以表明用它們都能設(shè)計(jì)出線程安全的Servlet程序。但是,如果一個(gè)Servlet實(shí)現(xiàn)了 SingleThreadModel接口,Servlet引擎將為每個(gè)新的請(qǐng)求創(chuàng)建一個(gè)單獨(dú)的Servlet實(shí)例,這將引起大量的系統(tǒng)開銷。 SingleThreadModel在Servlet2.4中已不再提倡使用;同樣如果在程序中使用同步來保護(hù)要使用的共享的數(shù)據(jù),也會(huì)使系統(tǒng)的性能大大 下降。這是因?yàn)楸煌降拇a塊在同一時(shí)刻只能有一個(gè)線程執(zhí)行它,使得其同時(shí)處理客戶請(qǐng)求的吞吐量降低,而且很多客戶處于阻塞狀態(tài)。另外為保證主存內(nèi)容和線 程的工作內(nèi)存中的數(shù)據(jù)的一致性,要頻繁地刷新緩存,這也會(huì)大大地影響系統(tǒng)的性能。所以在實(shí)際的開發(fā)中也應(yīng)避免或最小化 Servlet 中的同步代碼;在Serlet中避免使用實(shí)例變量是保證Servlet線程安全的最佳選擇。從Java 內(nèi)存模型也可以知道,方法中的臨時(shí)變量是在棧上分配空間,而且每個(gè)線程都有自己私有的??臻g,所以它們不會(huì)影響線程的安全。

          posted on 2007-07-10 09:34 冰封的愛 閱讀(360) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆檔案

          文章分類

          文章檔案

          相冊(cè)

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 称多县| 远安县| 简阳市| 文昌市| 沽源县| 垫江县| 嵊泗县| 富平县| 五寨县| 新化县| 漾濞| 博乐市| 井陉县| 霍山县| 扶沟县| 灵宝市| 上林县| 开平市| 惠州市| 休宁县| 尼勒克县| 聂荣县| 乌什县| 周宁县| 阿克| 乐至县| 扶余县| 石门县| 佳木斯市| 盐津县| 兴隆县| 永春县| 宽甸| 瓦房店市| 安仁县| 上林县| 个旧市| 商南县| 萨迦县| 澜沧| 泽普县|