浏览 6715 次
锁定老帖子 主题:web的threadlocal的使用疑问
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-07-12
如果是这样,那么如果某个session中设置了threadlocal保存线程变量,那么当这个session退出后,另一个session又使用了这个线程,其中threadlocal变量依然存在,并影响这个新的session. 这样的话,在线程池的环境下,是不是不能采用threadlocal来保存线程变量 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-07-12
这里说session不太合适吧,应该是request。
每个request处理结束,如果不希望thread local变量影响下一个request的话,应该把它清除掉. |
|
返回顶楼 | |
发表时间:2006-07-12
谢谢你的回覆
的却应该是request. 我打算采用的方法和你说的差不多,我在每个request中,当有对dao的请求,就重新设置当前threadlocal的值,这样在当前request中,就使用这个新的线程变量了. |
|
返回顶楼 | |
发表时间:2006-07-12
如果是Thread Pool.
对于同一个Thread来说,Thread Local 可能是同一个。 Thread Local的实现大致是一个Application Global Map结构。 {Thread Name, Thread Local Variable Name} 为 Key。 {Thread Name, Thread Local Variable Name} -> Thread Local Variable Value |
|
返回顶楼 | |
发表时间:2006-07-13
我的一点理解:
对于ThreadLocal,可以理解为使用Thread.currentThread();作为key的HashMap.(当然,实质上不是这样的,是一个ThreadLocalMap绑定在Thread上,然后存取这个ThreadLocalMap).平常都使用static ThreadLocal避免并发冲突,但这里有一个关于Web应用的假象:不同的request就应该对应不同的Thread.在并发访问时,这个应该是成立的.但是由于各种WebContainer的实现,对于非并发访问的request,完全可能取得同样的Thread.测试代码如下: <% System.err.println("current Thread===>" + Thread.currentThread(););; %> <form method="post"> <input type="submit"> </form> 同时打开两个浏览器,分别访问,看看后台日志.然后关掉其中一个浏览器,再重新打开一个新的浏览器,看看这次后台日志里打出的current Thread名称. 而我们又都使用了static的ThreadLocal保存资源,先后不同的request又得到了相同的Thread,所以就会发现各种诡异现象,不同的request取得了相同的东西. ----- @codeutil 我觉得如果是同一个线程被重用,那ThreadLocal里的东西也应该一样,都是保留的对象引用,准确说对象的内存地址相同.对线程池不是很了解,猜测而已.但正如大家所说,需要从ThreadLocal里清除资源,因为下一个request可能会用到. 个人感觉你的requestLocal可以不清除,request也使用了池缓冲.下一次request可能会使用上一次request的那个HttpServletRequest对象.但里面的参数什么的都是对应本次request. |
|
返回顶楼 | |
发表时间:2006-07-13
////////////先后不同的request又得到了相同的Thread
这是线程池的远程池的缘故!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 但是并不能够说明 ThreadLocal里的东西就是一样的, 因为一个线程只有接受并处理完一个request之后,才回还回线程池接受下一个请求. 因此除了要保存到ThreadLocal还需要从ThreadLocal中清楚 因此一般用过滤器把request保存到ThreadLocal, spring 的 OpenSessionInViewFilter就是这样的, HibernateSessionFactory的示例代码也是如此: 我自己写的是这样的: private static final ThreadLocal<HttpServletRequest> requestLocal = new ThreadLocal<HttpServletRequest> ();; private static final ThreadLocal<HttpServletResponse> responseLocal = new ThreadLocal<HttpServletResponse> ();; public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain); { requestLocal.set( (HttpServletRequest); request);; responseLocal.set( (HttpServletResponse); response);; filterChain.doFilter(request, response);; } catch (ServletException sx); { filterConfig.getServletContext();.log(sx.getMessage(););; } catch (IOException iox); { filterConfig.getServletContext();.log(iox.getMessage(););; } finally{ requestLocal.set( null);; responseLocal.set(null);; } } |
|
返回顶楼 | |