乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Servlet的多線程安全問(wèn)題

       zhngjan 2014-06-14
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public class MyServlet extends HttpServlet {
              final static int i = 0;
              public void doGet(HttpServletRequest req, HttpServletResponse res) {
                  private HttpSession session = req.getSession();
                  private ServletContext ctx = getServletContext();
                  synchronized (ctx) {
                      Object obj = ctx.getAttribute();
                      // code to alter obj
                  }
              }
          }

      上面代碼中的哪些變量是線程安全的?

      選擇:

      * A. i
      * B. session
      * C. ctx
      * D. req
      * E. obj
      * F. res

      IBM 給出的答案是:

      正確答案:

      * A、C、D 和 F

      說(shuō)明:

      靜態(tài)變量 i 是線程安全的,因?yàn)樗?final(不能被修改),否則它將不是安全的。請(qǐng)求和響應(yīng)對(duì)象的作用域只在請(qǐng)求的生命周期,因此它們也是線程安全的。會(huì)話和 ServletContext 對(duì)象可以從多個(gè)線程訪問(wèn),同時(shí)處理多個(gè)請(qǐng)求,因此它們不是線程安全的。但在本例中,同步了 ServletContext 對(duì)象,因此它只能由一個(gè)線程一次訪問(wèn)。obj 不是線程安全的,因?yàn)榧词雇搅?ServletContext 對(duì)象,它的屬性也沒(méi)有同步。它們需要另外進(jìn)行同步。因此,選項(xiàng) B 和 E 是不正確的,而選項(xiàng) A、C、D 和 F 是正確的。

      Servlets的多線程安全
      多線程占用資源少,處理速度快,提高了效率。
      一些編碼建議:
      對(duì)變量和方法定義適當(dāng)?shù)脑L問(wèn)方式, 例如單純?nèi)≈挡僮鞑粫?huì)有多線程安全問(wèn)題;
      同步化所有訪問(wèn)重要數(shù)據(jù)的實(shí)例變量; 多線程下,如果操作的是一個(gè)變量,且兼有讀寫操作,
      就要考慮加上同步,但同步不能亂加,否則會(huì)造成死鎖問(wèn)題。

      并發(fā)需要注意的
      并發(fā)的環(huán)境:資源處于一個(gè)并發(fā)的環(huán)境
      共享資源:多個(gè)線程共享一個(gè)臨界資源
      全面同步:如有n個(gè)變量訪問(wèn)同一個(gè)資源,這n個(gè)變量都得同步。即多個(gè)鎖一把鑰匙,鑰匙放在一個(gè)共享區(qū)域內(nèi)
      sychronized(this):粗粒度的鎖。是將所有的路都加鎖;
      sychronized(object o1):細(xì)粒度的鎖。只對(duì)對(duì)象中的變量加鎖。效率較前面的高,但是較難控制。
      讀寫需要互斥。
      sychronized(this):this不能是基本數(shù)據(jù)類型,必須是Object.不鎖對(duì)象的引用,而是對(duì)象的內(nèi)存空間。
      servlet中需要同步的:成員變量、文件、靜態(tài)變量、數(shù)據(jù)庫(kù)連接

      一,servlet容器如何同時(shí)處理多個(gè)請(qǐng)求。
      Servlet采用多線程來(lái)處理多個(gè)請(qǐng)求同時(shí)訪問(wèn),Servlet容器維護(hù)了一個(gè)線程池來(lái)服務(wù)請(qǐng)求。
      線程池實(shí)際上是等待執(zhí)行處理的一組線程,也叫做工作者線程(Worker Thread),
      Servlet容器使用一個(gè)調(diào)度線程來(lái)管理工作者線程(Dispatcher Thread)。

      當(dāng)容器收到一個(gè)訪問(wèn)Servlet的請(qǐng)求,調(diào)度者線程從線程池中選出一個(gè)工作者線程,將請(qǐng)求傳遞給該線程,
      然后由該線程來(lái)執(zhí)行Servlet的service方法。
      當(dāng)這個(gè)線程正在執(zhí)行的時(shí)候,容器收到另外一個(gè)請(qǐng)求,調(diào)度者線程將從池中選出另外一個(gè)工作者線程來(lái)服務(wù)新的請(qǐng)求;
      容器并不關(guān)心這個(gè)請(qǐng)求是否訪問(wèn)的是同一個(gè)Servlet還是另外一個(gè)Servlet;
      當(dāng)容器同時(shí)收到對(duì)同一Servlet的多個(gè)請(qǐng)求,那這個(gè)Servlet的service方法將以多線程方式并發(fā)執(zhí)行。

      二,Servlet容器默認(rèn)采用單實(shí)例多線程的方式來(lái)處理請(qǐng)求,減少產(chǎn)生Servlet實(shí)例的開銷,提升了對(duì)請(qǐng)求的響應(yīng)。
      對(duì)于Tomcat可以在server.xml中通過(guò)元素設(shè)置線程池中線程的數(shù)目。
      就實(shí)現(xiàn)來(lái)說(shuō):
      調(diào)度者線程類所擔(dān)負(fù)的責(zé)任是調(diào)度線程,只需要利用自己的屬性完成自己的責(zé)任。
      而其他對(duì)象又依賴于該對(duì)象所承擔(dān)的責(zé)任,需要得到該特定對(duì)象,那該類就是一個(gè)單例模式的實(shí)現(xiàn)了。

      三,如何開發(fā)線程安全的Servlet
      1,變量的線程安全:這里的變量指字段和共享數(shù)據(jù)(如表單參數(shù)值)。

      a,將參數(shù)變量本地化:多線程并不共享局部變量.所以我們要盡可能的在servlet中使用局部變量。
      例如:String user = request.getParameter(“user”);

      b,使用同步塊Synchronized,防止可能異步調(diào)用的代碼塊。這意味著線程需要隊(duì)列處理。
      在使用同板塊的時(shí)候要盡可能的縮小同步代碼的范圍,不要直接在sevice方法和響應(yīng)方法上使用同步,這樣會(huì)嚴(yán)重影響性能。

      2,屬性的線程安全分析:ServletContext,HttpSession,ServletRequest對(duì)象的屬性

      ServletContext:(線程是不安全的)
      ServletContext是可以多線程同時(shí)讀/寫屬性的,線程是不安全的。要對(duì)屬性的讀寫進(jìn)行同步處理或者進(jìn)行深度Clone()。
      所以在Servlet上下文中盡可能少地保存頻繁改寫的數(shù)據(jù),可以采取其他方式在多個(gè)Servlet中共享,比方我們可以使用單例模式來(lái)處理共享數(shù)據(jù)。
      HttpSession:(線程是不安全的)
      HttpSession對(duì)象在用戶會(huì)話期存在,只能處理屬于同一個(gè)Session的請(qǐng)求的線程,因此Session對(duì)象的屬性訪問(wèn)理論上是線程安全的。
      當(dāng)用戶打開多個(gè)同屬于一個(gè)進(jìn)程的瀏覽器窗口,在這些窗口的訪問(wèn)屬于同一個(gè)Session,會(huì)出現(xiàn)多次請(qǐng)求,需要多個(gè)工作線程來(lái)處理請(qǐng)求,可能造成同時(shí)多線程讀寫屬性,這時(shí)我們對(duì)屬性的讀寫進(jìn)行同步處理。
      ServletRequest:(線程是安全的)
      對(duì)于每一個(gè)請(qǐng)求,由一個(gè)工作線程來(lái)執(zhí)行,都會(huì)創(chuàng)建有一個(gè)新的ServletRequest對(duì)象,所以ServletRequest對(duì)象只能在一個(gè)線程中被訪問(wèn)。ServletRequest是線程安全的。
      注意:ServletRequest對(duì)象在service方法的范圍內(nèi)是有效的,不要試圖在service方法結(jié)束后仍然保存請(qǐng)求對(duì)象的引用。

      3,使用同步的集合類:
      使用Vector代替ArrayList,使用Hashtable代替HashMap。

      4,不要在Servlet中創(chuàng)建自己的線程來(lái)完成某個(gè)功能:
      Servlet本身就是多線程的,在Servlet中再創(chuàng)建線程,將導(dǎo)致執(zhí)行情況復(fù)雜化,出現(xiàn)安全問(wèn)題。

      5,在多個(gè)servlet中,對(duì)外部對(duì)象(例如文件)進(jìn)行修改操作一定要加鎖,做到互斥的訪問(wèn)

      四,SingleThreadModel接口
      javax.servlet.SingleThreadModel接口是一個(gè)標(biāo)識(shí)接口,如果一個(gè)Servlet實(shí)現(xiàn)了這個(gè)接口,
      則Servlet容器將保證在同時(shí)刻僅有一個(gè)線程可以在該servlet實(shí)例的service方法中執(zhí)行,將其他所有請(qǐng)求進(jìn)行排隊(duì)。
      服務(wù)器可以使用多個(gè)實(shí)例來(lái)處理請(qǐng)求,代替單個(gè)實(shí)例的請(qǐng)求排隊(duì)帶來(lái)的性能問(wèn)題。

      服務(wù)器可創(chuàng)建一個(gè)Servlet類的多個(gè)實(shí)例組成的實(shí)例池,對(duì)于每個(gè)請(qǐng)求分配Servlet實(shí)例進(jìn)行響應(yīng),之后放回到實(shí)例池中等待下此請(qǐng)求。此時(shí),局部變量(字段)也是安全的,但對(duì)于全局變量和共享數(shù)據(jù)是不安全的,需要進(jìn)行同步處理。
      而對(duì)于這種多實(shí)例的情況,使用SingleThreadModel接口并不能解決并發(fā)訪問(wèn)產(chǎn)生的問(wèn)題,
      且SingleThreadModel接口在servlet規(guī)范中已經(jīng)被明確聲明為deprecated了。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多