代码理解:
// 借助ThreadLocal对象每个线程只创建一个实例public static final String dateFormat="yyyy-MM-dd";PRivate static final ThreadLocal<DateFormat> dfThreadLocal=new ThreadLocal<DateFormat>(){ @Override protected DateFormat initialValue() { return new SimpleDateFormat(dateFormat); }};public static String dateToString(Date date){ return dfThreadLocal.get().format(date);} 对于每个线程,都有一个类似于Map的东西ThreadLocalMap(ThreadLocal的静态类 ),那它里面保存了什么东东呢,肯定是key-value啊,key就是上面代码中的共享静态变量 dfThreadLocal,value就是DateFormat实例了,即new SimpleDateFormat(dateFormat)这个东东。那接下来,在线程内我要如何去获取这个值呢,就是靠dfThreadLocal.get()实现滴,方法源码如下:ThreadLocal .ThreadLocalMap inheritableThreadLocals = null ;public T get () { Thread t = Thread.currentThread (); ThreadLocalMap map = getMap(t );// 获取到inheritableThreadLocals if ( map != null) { ThreadLocalMap.Entry e = map.getEntry (this);// this作为key,this就是本地线程变量,获取Entry if ( e != null) return ( T)e .value; } return setInitialValue ();}ThreadLocalMap getMap (Thread t) { return t .inheritableThreadLocals;} 可以很明显的看出,首先根据Thread.currentThread ()获取到inheritableThreadLocals(即ThreadLocalMap,他是Thread的一个变量),然后将this(即最上面代码的dfThreadLocal对象)作为key(或索引)获取到真正的值T(就是SimpleDateFormat对象)啊,至此应该比较清楚了,为什么不同的线程有各自的值,因为 不同的线程--->不同的ThreadLocalMap对象(线程的变量)--->通过相同的key(如果有被static修饰)获取到不同的value值。备注:一般都被static修饰,因为可以避免在一个线程内可能发生的重复创建TSO(Thread Specific Object,即ThreadLocal所关联的对象),被statis修饰了,同一线程key也肯定一样,value也肯定只有一份了。 一个ThreadLocal实例关联当前线程的一个TSO对象,如果把ThreadLocal声明为实例变量,那么每创建一个类实例就会导致一个TSO实例诞生,这肯定没有这个必要滴。更多文章请见我的个人博客:http://www.acanblog.com
新闻热点
疑难解答