2013-11-04 46 views
0

是会话线程安全的添加对象吗?将会话添加到会话线程安全

在我的jsp文件中,我正在检查会话是否不包含我的对象,然后我从数据库中获取并将其放入会话中。

此操作是否线程安全(以防多个请求同时到达同一行代码)?

+0

不,你可以通过添加序列化和同步 –

+0

“会话”本身及其上下文管理器不是线程安全的,你需要利用会话挖掘类,并把业务放在一个同步的方法中。 – 2013-11-04 06:54:25

+0

但是,当2个线程尝试将对象添加到会话时,什么情况可以打破任何东西? – kenny

回答

0

访问HttpSession属性不是线程安全的。执行请求线程的多个servlet可能同时具有对同一会话对象的主动访问权限。

开发人员有责任对属性对象本身进行线程安全访问。您可以在session对象上同步的get/set属性吧:

HttpSession session=request.getSession(); 
synchronized(session) 
{ 
//get/set attributes to session object 
} 
+0

但会话是“每个用户”,这意味着每个用户都会得到他自己的会话对象,这是不正确的? – kenny

+0

是的,它是正确的。但同一个用户可以打开多个浏览器(窗口选项卡)并发送请求。在这种情况下,对于同一个用户,多个请求可以进入servlet,并且在执行'HttpSession session = request.getSession();'时,同一会话实例在多个线程中可用。所以如果你不会在会话上进行同步,一个线程可能会不知不觉地覆盖另一个线程放置的值。 –

0

即使有单个会话(用户或连接)的基础上的SessionID,任意数量的并发请求的,可以从启动该用户在给定的会话中。例如,用户可能正在加载与编写代码相同的JSP文件,以便将数据库中的对象添加到会话中。

以下是一个示例代码来表示您可能正在编写的内容。

object = session.getAttribute("key"); 
if (object == null) { 
    object = getObjectFromDB(); 
    session.setAttribute("key", object); 
} 

由于线程切换可以在上面的代码段中的任何线发生,有一种可能性,即多个线程注意到的object作为null并试图把对象带入会话。由于使用相同的键每次调用session.setAttribute(key,value)都会覆盖现有值,因此不会引发错误。

但是,您将不得不考虑您的业务需求,并查看多次调用getObjectFromDB()是否会不必要地导致业务预期问题。