我有一个对象存储在 session 中。在我的 Controller 中,当用户发送请求时,它并发执行以下代码:
MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
while(!obj.isNewResultAvailable()){
//will loop until new result is available.
}
正如我所指出的,它是并发执行的,因此当控件仍在循环内时,用户可以做一些其他事情,例如,当用户按下另一个按钮时,将向 Controller 发送请求, Controller 执行以下:
MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
obj = null;
我的预期是,循环直到出现新结果的代码将抛出 NullPointerException
。才发现我们的不是。
那么,为什么从另一个 Controller 的 session 中拉取的对象不是 null
,尽管将该对象设置为另一个 Controller 为 null
?
编辑:
在我目前的代码中,我实际上尝试过这样做
req.getSession().setAttribute("myObject", null);
和
req.getSession().removeAttribute("myObject");
仍然没有解决我的问题,while 循环中的对象仍然没有被清空。
实现
对于那些会遇到这种困惑的人,我问题的根源是我对 Java 中对象的传递方式感到困惑。我的问题很简单,obj = null
只是将 obj
的 reference 设置为 null 而NOT对象本身。
正如 morgano 所指出的, session 中的对象已被执行 while 循环的线程在本地引用,因此,req.getSession().setAttribute("myObject", null);
并且 req.getSession().removeAttribute("myObject");
不会导致对象无效。这些基本上只是从 session 中删除对对象的引用(因此理想情况下使其成为 gc 的候选对象,这在我的情况下不会发生,因为该对象是由长时间运行的 http 请求 [while 循环] 在本地引用的) .
最佳答案
不要那样做,这样做:
req.getSession().setAttribute("myObject", null);
或更好:
req.getSession().removeAttribute("myObject");
您所做的是将对对象的引用设置为 null,您根本没有修改 session 属性。
问题版本后更新:
一旦“迭代”线程引用了您的对象,“删除”线程将其从 session 中删除是徒劳的,您的对象已被第一个线程中的局部变量引用。
关于java - 尽管明确将其设置为空,但对 session 属性的引用未变为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17800902/