论坛首页 Java企业应用论坛

关于ThreadLocal模式的体会

浏览 23588 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-03-18  
61234865 写道
我有一个地方不太明白,就是我们用SSH的时候,如果你用threadlocal来存变量,你第二次请求的时候怎么能保证获取到的线程就是和先前的线程一样的?如果不一样,那数据岂不是就丢失了?


这个问题的关键在于在web环境下怎么使用。
一般是使用Filter技术,在web.xml配置好,filter里的伪代码是这样:

doFilter(){
设置threadlocal变量;
filterChain.doFilter();
清除threadlocal变量;
}



这样就保证了在Action、JSP里都可以获得本线程的threadlocal变量。
注意:一次web 请求肯定是由一个线程来完成响应的。
0 请登录后投票
   发表时间:2010-03-18  
LucasLee 写道
61234865 写道
我有一个地方不太明白,就是我们用SSH的时候,如果你用threadlocal来存变量,你第二次请求的时候怎么能保证获取到的线程就是和先前的线程一样的?如果不一样,那数据岂不是就丢失了?


这个问题的关键在于在web环境下怎么使用。
一般是使用Filter技术,在web.xml配置好,filter里的伪代码是这样:

doFilter(){
设置threadlocal变量;
filterChain.doFilter();
清除threadlocal变量;
}



这样就保证了在Action、JSP里都可以获得本线程的threadlocal变量。
注意:一次web 请求肯定是由一个线程来完成响应的。

这样的用法就更清析了...
不知道还有可能会出什么问题.....
不想用了新的用法会出什么隐问题
0 请登录后投票
   发表时间:2010-03-18  

我还是觉得,像这样用超出了ThreadLocal的意图。

如果在一个业务流程真的那么需要一个context存储上下文变量,那么我们应该找到一个map,把 “流程id映射map” 存储进去。

这样可以完全抛开Thread的概念,业务方法就不会把底层的东西都依赖进来。

 

ThreadLocal还是应该应用在处理多线程的问题中。

 

 

0 请登录后投票
   发表时间:2010-03-18  
webwork和struts2都用了这个东西。
0 请登录后投票
   发表时间:2010-03-19   最后修改:2010-03-19
x_root 写道
webwork和struts2都用了这个东西。

是地,以前给项目国际化的时候用过这个。可以把rquest放在ThreadLocal里面,这样在任何方法内都可以得到当前登录用户,有时定义某个接口可能忽略了一些参数,可以这样做。。。
0 请登录后投票
   发表时间:2010-03-22  
抛出异常的爱 写道
不知道有哪个项目是这么用的.

可以解决很多参数问题.



举一个例子-CXF,很多很多。
0 请登录后投票
   发表时间:2010-03-22  
yimlin 写道
通常用来解决框架中的上下文对象,业务级的通常还是传参解决,这样业务上更为明确。



很赞同你的观点。
0 请登录后投票
   发表时间:2010-04-01  
threadlocal 应该只用来解决多线程问题, 如果用来解决参数传递问题, 表面上看.影响了业务分层. 实际上也给以后扩展带来隐患. 比如说service层或者数据访问层写好后因为需要,想提供给对外接口复用.问题就来了
0 请登录后投票
   发表时间:2010-04-01  
我通常把User放到ThreadLocal中
0 请登录后投票
   发表时间:2010-04-01  
ThreadLocal不是用来解决对象共享访问问题的
我不太同意这个观点,现在比如有如下的代码。这个format方法有2个线程循环的访问,每次访问完可以放回线程池中,但是因为SimpleDateFormat不是线程安全的类,所以这样访问肯定会出现并发的错误!
public class Foo {
	
	static SimpleDateFormat formator = new SimpleDateFormat("yyMMddHHmmss");
	
	public static String format(Date date) {
		return formator.format(date);
	}

}


那么为了避免并发的错误,可以有如下2中方案,1加synchronized,这样每次只有一个线程访问这个方法,对性能有影响
public static synchronized String format(Date date) {
		return formator.format(date);
	}

2,每次调用这个方法就生成一个新的SimpleDateFormat对象,这样会生成大量的对象,对性能不是很好
public static String format(Date date) {
		SimpleDateFormat formator = new SimpleDateFormat("yyMMddHHmmss");
		return formator.format(date);
	}


那么如果用ThreadLocal就可以解决创建大量对象的问题和并发访问的问题,重复利用SimpleDateFormat对象
public class Foo {
	static ThreadLocal local = new ThreadLocal();
	
	public static String format(Date date) {
		SimpleDateFormat formator = (SimpleDateFormat)local.get();
		if (formator == null) {
			formator = new SimpleDateFormat("yyMMddHHmmss");
			local.set(formator);
		}
		return formator.format(date);
	}

}


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

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