• Java面试题09-ThreadLocal的底层原理


    Java面试题09-ThreadLocal的底层原理

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

    2、ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象(注意不是ThreadLocal对象)中都存在一个ThreadLocalMap,Map的key为ThreadLocal对象value为缓存的数据

    public class Test {
        private static ThreadLocal<String> s = new ThreadLocal<>();
        public static void main(String[] args) {
        	// 存入缓存
            s.set("zal");
            // 从缓存中获取
            String s = Test.s.get();
            System.out.println(s);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    	public void set(T value) {
    		Thread t = Thread.currentThread(); // 获取线程对象
    		ThreadLocalMap map = getMap(t); // 获取线程内部的属性 map
    		if(map != null) {
    			map.set(this, value); //缓存数据
    		} else {
    			createMap(t, value);  //新建缓存
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public T get() {
    	Thread t = Thread.currentThraed(); // 获取线程对象
    	ThreadLocalMap map = getMap(t); // 获取线程内部的属性 map
    	if(map != null) {
    		ThreadLocalMap.Entry e = map.getEntry(this); // 获取map中的对象
    		if(e != null) {
    			return (T)e.value; // 返回对应的值
    		} 
    	}
    	return setInitialValue(); // 返回初始化的值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、如果在线程池中使用ThreadLocal会造成内存泄漏。因为当ThreadLocal对象使用完之后,应该要把设置的key和value,也就是Entry对象进行回收,但线程池中的线程不会回收,而线程对象是通过强引用指向ThreadLocalMap,Thread LocalMap也通过强引用指向Entry对象,线程不被回收,Entry对象也不会被回收,从而出现内存泄漏,解决办法是,在使用了ThreadLocal对象之后,手动调用ThreadLocal的remove方法,手动清除Entry对象。

    线程 --> ThreadLocalMap --> key、value

    4、ThreadLocal的经典应用场景就是连接管理(一个线程持有一个连接,该连接的对象可以在不同的方法之间进行传递,线程之间不共享同一个连接)。

  • 相关阅读:
    Java8 新特性之Stream(三)-- Stream的终结操作
    webpack实战:最新QQ音乐sign参数加密分析
    UPnP协议和SSDP协议
    针对应用程序依赖库漏洞的攻击
    HTML5期末大作业:基于HTML+CSS+JavaScript实现中国风文化传媒企业官网源码
    Bootstrap学习(十一)
    HIVE多维分析函数:grouping sets、cube、rollup
    MongoDB的UTCDateTime如何使用
    Vue 实现拖拽模块
    Eureka原理实践
  • 原文地址:https://blog.csdn.net/z318913/article/details/126613803