3 回答

TA貢獻1872條經驗 獲得超4個贊
不,根據IBM- Java理論和實踐,它們不是線程安全的:所有有狀態的Web應用程序都損壞了嗎?。您需要同步。
從Java Ranch來看HttpSession如何不是線程安全的,這也可能會有所幫助。

TA貢獻1803條經驗 獲得超6個贊
Servlet 2.5規范:
執行請求線程的多個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);
這不能保證是安全的:
// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
Integer n = (Integer) session.getAttribute("foo");
session.setAttribute("foo", (n == null) ? 1 : n + 1);
}
我已經看到了所提倡的最后一種方法(包括J2EE書籍中的方法),但是Servlet規范不能保證它可以正常工作。您可以使用會話ID創建互斥體,但是必須有更好的方法。

TA貢獻1865條經驗 獲得超7個贊
在某些方面,這取決于您的客戶端設計。
在您的Web設計中,您是否有機會讓單個客戶端使用同一HTTP會話擁有多個未完成的同時請求?除非您將單個HTTP會話綁定到多個套接字,否則這似乎很難做到。(aka,AJAX)沒有這樣做,就服務器而言,給定客戶端的HTTP訪問將是單線程的,這意味著單個會話實際上是線程安全的。
會話對象的同步將使應用程序更安全,以防將來的更改使Web應用程序能夠同時發出多個請求,因此這不是一個壞主意。在現代Java實現中,同步并沒有以前帶來的高昂成本,尤其是在通常不爭用同步的情況下。如果您的應用程序使用AJAX,這意味著您希望向Web服務器發送多個正在進行的同時請求,那么必須進行同步。
添加回答
舉報