原创整理不易,转载请注明出处:
代码下载地址:
ThreadLocal是为了使每个线程保存一份属于自己的数据。
先看一个使用ThreadLocal的实例。
上例展示的是spring框架中获取当前线程的代理对象的方法,AopContext.currentProxy(),在本线程的程序调用栈中只要调用AopContext的静态方法就可以获取本线程相关的代理对象。如果不用ThreadLocal,那么这个代理对象在创建后,就要一层层传递下去,才能在后面获取到并使用。
通过这个例子,我们可以知道[b]ThreadLocal主要是提供了一种保持对象的方法以及避免了对象在程序调用中传递的简便访问方法。ThreadLocal与共享数据和同步没有明显关系。[/b]
下面看看相关的源码以了解具体的结构。
从Thread的源码中可以得知,是每一个Thread持有一个自己的map,并不是一个ThreadLocal持有一个map。
使用ThreadLocal过程: 对于每一个需要线程保存自身实例的变量,需要定义一个静态的ThreadLocal实例。然后将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象。
此外,每个线程保存的自身数据并不是通过备份或复制的,而是new创建出来的。
通过ThreadLocal各个线程只能获取自身对应的数据,不能访问其他线程的数据,但是如果两个线程在set时引用了同一个数据,仍然存在同步问题。