2012-07-20 130 views
0

RollerSession具有下面的代碼:會話安全違規

public static RollerSession getRollerSession(HttpServletRequest request) { 
    RollerSession rollerSession = null; 
    HttpSession session = request.getSession(false); 
    if (session != null) { 
     rollerSession = (RollerSession)session.getAttribute(ROLLER_SESSION); 
     if (rollerSession == null) { 
      // HttpSession with no RollerSession? 
      // Must be a session that was de-serialized from a previous run. 
      rollerSession = new RollerSession(); 
      session.setAttribute(ROLLER_SESSION, rollerSession); 
     } 
     .... 

我是新來的併發問題。這裏似乎有兩個不同的線程可能會同時更新setAttribute,這是違反原子性的。是對的嗎?會話可以由兩個線程共享,因爲它是從請求中獲得的?

回答

1

是的,你說的對,還有一個可見性問題!根據IBM's postJava Ranch get/set操作是不是線程安全。所以,如果你不想在你的應用中出現任何競爭條件,你應該同步,但要注意同步的位置。

說明

執行請求線程多個servlet可以具有在同一時間活動的接入同一會話的對象。容器必須確保以線程安全的方式執行表示會話屬性的內部數據結構。開發人員有責任對屬性對象本身進行線程安全訪問。這將保護HttpSession對象內的屬性集合免受併發訪問,從而消除了應用程序導致該集合損壞的機會。

這是安全的:

// guaranteed by the spec to be safe 
request.getSession().setAttribute("foo", 1); 

這是安全:

HttpSession session = request.getSession(); 
Integer n = (Integer) session.getAttribute("foo"); 
// not thread safe 
// another thread might be have got stale value between get and set 
session.setAttribute("foo", (n == null) ? 1 : n + 1); 

- McDowell's Answer

+0

感謝waldyr。這回答了我的問題。 – user1539577 2012-07-20 04:06:22

+0

我們爲此而努力!我會很感激,如果你可以upvote我的答案或選擇作爲問題的答案。 – 2012-07-20 11:43:04