以下是 ThreadLocal 类方法源码解析:
1. get()
:获取当前线程的 ThreadLocal 变量的值。如果变量尚未被当前线程设置,则返回 null。
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
解释:该方法首先获取当前线程 Thread.currentThread()
。
然后,调用 getMap(t)
方法获取当前线程的 ThreadLocalMap
对象 map
。
如果 map
不为 null
,表示当前线程已经有一个 ThreadLocalMap
,可以尝试获取与当前 ThreadLocal
对象关联的值。
调用 map.getEntry(this)
方法,传入当前 ThreadLocal
对象作为参数,获取与之关联的 Entry
节点 e
。
如果 e
不为 null
,表示找到了与当前 ThreadLocal
对象关联的值。通过强制类型转换将 e.value
转换为泛型类型 T
,并将其赋值给 result
变量。
最后,返回 result
,即当前线程中与当前 ThreadLocal
对象关联的值。
如果 map
为 null
或者未找到与当前 ThreadLocal
对象关联的值,则调用 setInitialValue()
方法来设置初始值,并返回该值。
总之,get()
方法用于获取当前线程中与当前 ThreadLocal
对象关联的值。它首先获取当前线程的 ThreadLocalMap
对象,然后在该对象中查找与当前 ThreadLocal
对象关联的值。如果找到了值,则返回该值;否则,设置初始值并返回。
2. setInitialValue()
:该方法用于设置线程本地变量的初始值,并将其与当前线程关联起来。
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
以下是该方法的具体步骤:
- 调用
initialValue()
方法获取线程本地变量的初始值,将其赋给变量value
。 - 获取当前线程
Thread.currentThread()
。 - 调用
getMap(Thread t)
方法获取当前线程对应的ThreadLocalMap
对象,并将其赋给变量map
。 - 检查
map
是否为null
。如果不为null
,表示当前线程已经有一个ThreadLocalMap
对象,可以直接调用map.set(this, value)
方法将当前ThreadLocal
对象和对应的值存入map
中。 - 如果
map
为null
,表示当前线程还没有ThreadLocalMap
对象,调用createMap(t, value)
方法创建一个新的ThreadLocalMap
对象,并将当前ThreadLocal
对象和对应的值存入新创建的map
中。 - 返回
value
,即线程本地变量的初始值。
这个方法的作用是在首次访问线程本地变量时,为其设置初始值,并将其与当前线程关联起来。如果当前线程已经有一个 ThreadLocalMap
对象,则直接存入对应的键值对;如果当前线程还没有 ThreadLocalMap
对象,则创建一个新的 ThreadLocalMap
对象,并将键值对存入其中。
需要注意的是,setInitialValue()
方法是作为 ThreadLocal
类的内部方法使用的,在我们使用 ThreadLocal
类时并不需要直接调用它。
3. set(T value)
:该方法用于将指定的值 value
关联到当前线程中的当前 ThreadLocal
对象。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
解释:该方法首先获取当前线程 Thread.currentThread()
。
然后,调用 getMap(t)
方法获取当前线程的 ThreadLocalMap
对象 map
。
如果 map
不为 null
,表示当前线程已经有一个 ThreadLocalMap
,可以直接调用 map.set(this, value)
方法将当前 ThreadLocal
对象和指定的值 value
关联起来。
如果 map
为 null
,表示当前线程还没有 ThreadLocalMap
,需要调用 createMap(t, value)
方法来创建一个新的 ThreadLocalMap
并将其与当前线程关联起来。
总之,set(T value)
方法用于将指定的值关联到当前线程中的当前 ThreadLocal
对象。它首先获取当前线程的 ThreadLocalMap
对象,然后根据是否存在该对象来选择直接设置值或创建新的 ThreadLocalMap
对象。
4. remove()
:该方法用于从当前线程的 ThreadLocalMap
中移除与当前 ThreadLocal
对象关联的值。
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
解释:该方法首先通过调用 getMap(Thread.currentThread())
方法获取当前线程的 ThreadLocalMap
对象 m
。
如果 m
不为 null
,表示当前线程有一个 ThreadLocalMap
对象,可以调用 m.remove(this)
方法来移除与当前 ThreadLocal
对象关联的值。
如果 m
为 null
,表示当前线程没有 ThreadLocalMap
对象,无需进行任何操作。
总之,remove()
方法用于从当前线程的 ThreadLocalMap
中移除与当前 ThreadLocal
对象关联的值。它首先获取当前线程的 ThreadLocalMap
对象,然后根据是否存在该对象来选择是否进行移除操作。
5. initialValue()
:该方法用于提供一个初始值,以便在首次访问 ThreadLocal
对象时使用。
protected T initialValue() {
return supplier.get();
}
解释:该方法调用了一个 supplier.get()
方法来获取初始值。这里的 supplier
是一个 Supplier<T>
类型的对象,它提供了一个无参数的 get()
方法,用于获取初始值。
通过重写 initialValue()
方法,我们可以自定义初始值的生成逻辑。默认情况下,如果没有手动设置初始值,ThreadLocal
的初始值为 null
。
总之,initialValue()
方法用于提供一个初始值,在首次访问 ThreadLocal
对象时使用。通过重写该方法,我们可以自定义初始值的生成逻辑。
6. withInitial(Supplier<? extends T> supplier)
:该方法用于创建一个具有初始值供应者的 ThreadLocal
对象。
public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
return new SuppliedThreadLocal<>(supplier);
}
解释:该方法使用提供的 Supplier
对象来创建一个 SuppliedThreadLocal
对象,该对象实现了 ThreadLocal
接口。Supplier
是一个函数式接口,它定义了一个无参数的 get()
方法,用于获取初始值。
通过调用 withInitial(supplier)
方法,我们可以创建一个具有初始值供应者的 ThreadLocal
对象。该供应者将在首次访问 ThreadLocal
对象时生成初始值。
总之,withInitial(Supplier<? extends S> supplier)
方法用于创建一个具有初始值供应者的 ThreadLocal
对象。通过该方法,我们可以方便地指定一个供应者来生成初始值。
7. getMap(Thread t)
:该方法用于获取给定线程 t
对应的 ThreadLocalMap
对象。
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
解释:在 ThreadLocal
类中,每个线程都有一个名为 threadLocals
的字段,它是一个 ThreadLocalMap
对象。该字段用于存储线程本地变量的键值对。
在 getMap(Thread t)
方法中,通过访问线程 t
的 threadLocals
字段,直接返回对应的 ThreadLocalMap
对象。
这个方法的作用是为了获取特定线程的 ThreadLocalMap
对象,以便进行后续的操作,比如获取或设置线程本地变量的值。
需要注意的是,getMap(Thread t)
方法是 ThreadLocal
类的内部方法,我们通常不需要直接调用它,而是通过 ThreadLocal
对象的方法间接地访问线程本地变量。
8. createMap(Thread t, T firstValue)
:该方法用于在当前线程中创建一个新的 ThreadLocalMap
对象,并将初始值与当前 ThreadLocal
对象关联起来。
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
以下是该方法的具体步骤:
- 接收一个线程对象
t
和一个初始值firstValue
作为参数。 - 创建一个新的
ThreadLocalMap
对象,并将当前ThreadLocal
对象和初始值作为参数传递给构造函数。 - 将新创建的
ThreadLocalMap
对象赋值给当前线程的threadLocals
字段,即将其与当前线程关联起来。
这个方法的作用是在当前线程中创建一个新的 ThreadLocalMap
对象,并将初始值与当前 ThreadLocal
对象关联起来。ThreadLocalMap
对象用于存储线程本地变量的键值对。通过将新创建的 ThreadLocalMap
对象赋值给当前线程的 threadLocals
字段,就可以在当前线程中使用 ThreadLocal
对象来获取和设置线程本地变量的值。
以上是 ThreadLocal 类常用方法的源码和详细解释。这些方法允许您在多线程环境中维护线程本地变量,并提供了获取、设置、移除 ThreadLocal 变量的功能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。