1. 程式人生 > >Head First Servlets and JSP】筆記9:屬性的作用域、線程安全

Head First Servlets and JSP】筆記9:屬性的作用域、線程安全

string details attr target 部分 ring 瀏覽器 什麽是 作用

什麽是屬性?

屬性和參數

屬性的3個作用域

屬性API

屬性不好的一面

1、到底什麽是屬性(Attribute)?

屬性就是一個對象,可以被設置(bound,也可以叫綁定)到另外三個servlet API對象ServletContext、HttpSession、HttpServletRequest中。可以把它簡單地認為是一個名/值對,名是String、值是object。在實際中,我們並不知道也不關心它具體如何實現,我們關心的只是屬性所在的作用域。

2、屬性不是參數(Parameter)!

筆記1中的參數——請求參數:

技術分享

筆記7中的參數——servlet初始化參數:

技術分享

技術分享

以及,上下文初始化參數參數:

技術分享

技術分享

3、屬性的3個作用域:

  • ServletContext屬性(上下文屬性)——Web應用中的每一部分都能訪問
  • HttpSession屬性(會話屬性)——能訪問特定的HttpSession的部分才可訪問
  • HttpServletRequest屬性(請求屬性)——能訪問特定的ServletRequest的部分才可訪問

4、設置、訪問屬性的API——每個接口(ServletContext、HttpS......)的屬性API完全相同

技術分享

關於Enumeration,參見Java-Enumeration總結 by IAMTJW

5、屬性不好的一面.··.```..``..`.`.`...`..

  1. 上下文屬性不是線程安全的!一個上下文屬性可能同時被多個servlet所更改、訪問。糟糕的解決方案是給doGet(或者是其它方法)加上synchronized,這樣並不能解決問題,原因在於關於synchronized只能防止同一個servlet中的其他線程訪問上下文屬性,但是不能阻止另外一個servlet訪問。關於ynchronized參見java synchronized詳解 by Gang.Wang。技術分享

    正確的方法是:對上下文加鎖,而不是對servlet加鎖。怎麽實現呢?看下面的代碼:技術分享

  2. 會話屬性是線程安全的嗎?不是,因為用戶可能打開好幾個瀏覽器窗口...解決方案類似:技術分享
  3. 只有請求屬性和局部變量是線程安全的!技術分享

    要註意的是servlet的實例域不是線程安全的,除非實現了SingleThreadModel,或者是同步服務方法,但這是十分糟糕的做法,會讓Web應用的效率變得非常差,所以,一個servlet根本不該有實例變量,有也應該是final的,如果真的需要在多個線程中共享一些東西,那就把它加到合適的作用域上去。

Head First Servlets and JSP】筆記9:屬性的作用域、線程安全