【面试题】ThreadLocal 的底层原理与使用场景

什么是ThreadLocal?

ThreadLlocal 是 Java 中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据。

可以看看一个简单的Demo:

public class ThreadLocalDemo {
    public static ThreadLocal<String> s = new ThreadLocal<>();

    public static void main(String[] args) {
		s.set("Harmony");
        String s1 = ThreadLocalDemo.s.get("");    
	}
}

ThreadLocal 底层原理

Threadlocal底层是通过 ThreadloalMap 来实现的。

Thread对象(注意不是ThreadLocal)中都存在 ThreadlocaMap,Map的keyThreadlocal对象Map的value为需要缓存的 

我们可以很清晰的看到,在ThreadLocal类中的确是有一个 ThreadLocalMap 作为静态内部类,但是它的使用却是在线程中(Thread里面)

我们可以看看它的 set()、get() 方法 

// ThreadLocal类
public void set(T value) {
	Thread t = Thread.currentThread();
	ThreadLocal.ThreadLocalMap map = getMap(t);
	if (map != null)
		map.set(this, value);
	else
		createMap(t, value);
}
public T get() {
	Thread t = Thread.currentThread();
	ThreadLocal.ThreadLocalMap map = getMap(t);
	if (map != null) {
		ThreadLocal.ThreadLocalMap.Entry e = map.getEntry(this);
		if (e != null) {
			@SuppressWarnings("unchecked")
			T result = (T)e.value;
			return result;
		}
	}
	return setInitialValue();
}

内存泄漏(线程池)

如果在线程池中使用ThreadLocal会造成内存泄漏。

ThreadLocal对象使用完之后,应该要把设置的 key、value (即:Entry对象)进行回收,但线程池中的线程不会回收,而线程对象是通过强引用指向 ThreadLocalMap,ThreadLocalMap也是通过强引用指向Entry对象,线程不被回收,Entry对象也就不会被回收,从而出现内存泄漏!!!

解决办法

在使用了ThreadLocal对象之后,手动调用ThreadLocal的 remove()方法,手动清除Entry对象!

使用场景

Threadlocal经典的应用场景就是连接管理

一个线程持有一个连接,该连接对象可以在不同的方法之间进行传递,线程之间不共享同一个连接。

猜你喜欢

转载自blog.csdn.net/weixin_43715214/article/details/131733959