3 回答

TA貢獻(xiàn)1872條經(jīng)驗(yàn) 獲得超4個(gè)贊
不,根據(jù)IBM- Java理論和實(shí)踐,它們不是線程安全的:所有有狀態(tài)的Web應(yīng)用程序都損壞了嗎?。您需要同步。
從Java Ranch來看HttpSession如何不是線程安全的,這也可能會(huì)有所幫助。

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊
Servlet 2.5規(guī)范:
執(zhí)行請(qǐng)求線程的多個(gè)servlet可以同時(shí)主動(dòng)訪問同一會(huì)話對(duì)象。容器必須確保以線程安全的方式對(duì)表示會(huì)話屬性的內(nèi)部數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作。開發(fā)人員負(fù)責(zé)對(duì)屬性對(duì)象本身進(jìn)行線程安全訪問。這將保護(hù)HttpSession對(duì)象內(nèi)部的屬性集合免受并發(fā)訪問,從而消除了應(yīng)用程序?qū)е略摷蠐p壞的機(jī)會(huì)。
這是安全的:
// 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);
}
我已經(jīng)看到了所提倡的最后一種方法(包括J2EE書籍中的方法),但是Servlet規(guī)范不能保證它可以正常工作。您可以使用會(huì)話ID創(chuàng)建互斥體,但是必須有更好的方法。

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