概念
ThreadLocal并不是用来解决多线程下的共享变量问题,而是提供县城内的线程访问。在多线程环境下,可以保证各个线程之间的变量相互隔离。
使用
public class ThreadLocalDemo implements Runnable{
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public void run(){
for (int i = 0; i < 3; i++) {
threadLocal.set(i);
System.out.println(Thread.currentThread().getName()+",value="+threadLocal.get());
}
}
public static void main(String[] args) {
ThreadLocalDemo demo = new ThreadLocalDemo();
new Thread(demo).start();
new Thread(demo).start();
}
}
实现原理
ThreadLocalMap是ThreadLocal内部类,有ThreadLocal创建,每一个Thread维护了一个ThreadLocal.ThreadLocalMap类型的属性threadLocals。所有的值都是存储在ThreadLocalMap中。
放入值
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//从当前线程中获取threadLocals
ThreadLocalMap map = getMap(t);
if (map != null)
//如果当前map不为空,说明之前创建过,以当前线程为key,将值存入其中
map.set(this, value);
else
//如果没有,那就创建
createMap(t, value);
}
获取值
public T get() {
//获取当前线程
Thread t = Thread.currentThread();
//从当前线程中获取threadLocals
ThreadLocalMap map = getMap(t);
if (map != null) {
//如果map不为null,获取key为当前线程的值
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//如果map为null,返回初始值,这个方法时一个
return 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;
}
//如果需要初始值,可以继承ThreadLocal,自己实现这个方法,返回一个初始化值
protected T initialValue() {
return null;
}
移除
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
内存泄漏问题
在获取值的get方法中,Entry类继承了WeakReference,即每个Entry对象都有一个ThreadLocal的弱引用,GC对弱引用采取的是积极的内存回售策略,避免了无人搭理时内存泄漏。
static class Entry extends WeakReference<ThreadLocal<?>> {
ThreadLocal对象只是作为ThreadLocalMap的一个key值而存在,现在他被回收了,那么value呢?针对这一问题,ThreadLocalMap类在每次set,get,remove的时候,会自动清理key值为null的value。如此一来,value就会被回收了
本文详细解析了ThreadLocal的工作原理,包括其如何实现线程变量隔离,避免多线程环境下的共享变量冲突。通过具体代码示例,展示了ThreadLocal的使用方式,并深入探讨了其内部实现机制,如ThreadLocalMap的作用及内存泄漏的预防策略。
10万+

被折叠的 条评论
为什么被折叠?



