就普通使用而言,应该使用 public/private static ThreadLocal tl = new ThreadLocal(),这样就可以满足所有线程的需要。
通过这个实例可以get/set一个值,请注意这一点很重要!对某个具体的线程而言,一个ThreadLocal实例就只表示一个值,也就是说在我们平时阅读代码的时候,我们把它看成一个值即可,不过是这个线程所独有的一个值,当然这里所说的一个值是指一个java对象,你大可以放一个Map,List,Array之类的从而一群值!
实际上,通过一个ThreadLocal实例,get/set值的时候,ThreadLocal内部实现会拿到当前线程所持有的ThreadLocalMap实例,ThreadLocalMap实例的本体其实是一个Entry数组,每一个Entry是键值对,其键就是前面说到的当前的ThreadLocal实例(是通过WeakReference持有的,为避免其影响GC造成内存泄漏),其值就是前面说到的那个值。
这样一来,如果我在一个或者多个类里定义了多个ThreadLocal,则具体的一个线程运行到这些代码的时候,其持有的ThreadLocalMap对应的那个Entry数组里就会有多个元素,自然每个元素对应一个ThreadLocal。
而,同时在运行的多个线程,由于本身就是多个线程实例,也由于每个线程都独自持有一个ThreadLocalMap,则自然在找寻目标值时不会访问到同一个,不会出现线程间数据混乱的情况了。
具体的细节可以查看JDK1.8 ThreadLocal源码,对着源码看就很容易理解以上所说的。
这个字体和排版看着真舒服:Java 8 ThreadLocal 源码解析 - -Finley- - 博客园 (cnblogs.com)