ThreadLocal使用场景:
避免引起线程安全问题,比如多个线程访问类的静态域.具体的一个示例,比如线程上下文仅需要唯一标志的变量,比如调用需要的token或者请求生成的唯一的key.
原理:
内部定义一个HaspMap<String,Object>当往里面放数据时,先获得当前线程的名字:String name =Thread.currentThread().getName();然后往Map中放数据,map.put(name,o);当key值不一样即线程的名字不一样的时候,取不出数据.但是如果有两个线程我们通过改名来实现2个线程同名,那么也是取不出数据的,因为java内部已经将每个线程起了唯一的名字,即使我们改了线程的名字也没用.
特点:
ThreadLocal与Set,Map一样,可以看作是一个容器,该不过该容器是一个单元素容器,因为内部的实现是以key是Thread的name,这样的类似的容器还有AutomReference.如果需要定义多个线程变量,就需要定义多个ThreadLoca<T> t*=new ThreadLocal<T>();
重置线程变量:
当你的ThreadLocal变量逃离了它的作用域时会引起的问题,你仍然是在同一个线程的上下文下,但作用域已经改变了。你可以将 ThreadLocal理解为一个线程内的全局变量,但你的应用规定这个ThreadLocal存在一定的逻辑作用域(比如一个request的处理), 当你跨作用域传递它而又不进行重置操作的话就可能会引起问题。
如果有多个线程变量在线程退出之前需要重置,可以利用ThreadLocalRegistry提供集中的重置处理,以防止由于“马虎”引 起的问题。
附:
线程模式方面的对比:Struts1中的action实例与Servlet都是单例模式,因为仅有Action的一个实例来处理所有的请求,所以线程安全很重要。Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题 。
当客户端请求时,[Servlet容器]会从[线程池]中[分配一个线程]给这个[请求]
参考:
http://www.blogjava.net/ShuyangZhou/archive/2010/01/25/310795.html
http://hi.baidu.com/310934797/blog/item/671a4086a8e3b82266096e80.html