首先要知道什么是ThreadLocal.
在多线程的环境中,每次进行线程切换都需要进行上下文切换,需要横跨若干方法调用非常的麻烦。
Java标准库提供了一个特殊的ThreadLocal
,它可以在一个线程中传递同一个对象。即与线程池创建线程不同的是:通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。
可以把ThreadLocal
看成一个全局Map<Thread, Object>
:每个线程获取ThreadLocal
变量时,总是使用Thread
自身作为key:
Object threadLocalValue = threadLocalMap.get(Thread.currentThread());
因此,ThreadLocal
相当于给每个线程都开辟了一个独立的存储空间,各个线程的ThreadLocal
关联的实例互不干扰。
以下是ThreadLocal的API:
set()
方法,设置当前线程中变量的副本。get()
方法,获取ThreadLocal
在当前线程中保存的变量副本。remove()
方法,清空当前线程中变量的副本。(在一个线程消失后,它的线程本地实例的所有副本都要接受垃圾回收(除非存在对这些副本的其他引用)。)initialValue()
是一个protected
方法,一般是用来重写的,如果在没有set的时候就调用get
,会调用initialValue
方法初始化内容。
通过HashCode
标识每个线程。可以消除在相同线程使用连续构造的 ThreadLocals 的常见情况下的冲突。
private final int threadLocalHashCode = nextHashCode();
其中还有个ThreadLocalMap
的结构用于声明和保存ThreadLocal
的值,并且为了能够应对庞大持久的使用,这个哈希表键值对还用了弱引用来避免内存泄漏。
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
他的初值为16,负载因子为2/3.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。