论坛首页 Java企业应用论坛

web的threadlocal的使用疑问

浏览 6715 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-07-12  
我在web应用中,好像几个不同的session会使用同一个线程,当然是不同登陆时间.这是不是由于tomcat采用了线程池的缘故呢?

如果是这样,那么如果某个session中设置了threadlocal保存线程变量,那么当这个session退出后,另一个session又使用了这个线程,其中threadlocal变量依然存在,并影响这个新的session.

这样的话,在线程池的环境下,是不是不能采用threadlocal来保存线程变量
   发表时间:2006-07-12  
这里说session不太合适吧,应该是request。

每个request处理结束,如果不希望thread local变量影响下一个request的话,应该把它清除掉.
0 请登录后投票
   发表时间:2006-07-12  
谢谢你的回覆
的却应该是request.

我打算采用的方法和你说的差不多,我在每个request中,当有对dao的请求,就重新设置当前threadlocal的值,这样在当前request中,就使用这个新的线程变量了.
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间: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.
0 请登录后投票
   发表时间: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);;
    }
  }

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics