栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java笔记——谈谈对ThreadLocal的理解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java笔记——谈谈对ThreadLocal的理解

1.什么是ThreadLocal?

ThreadLocal是Java为Thread提供的本地存储机制,可以在Thread通过ThreadLocal(set方法)缓存数据,缓存之后可以在线程执行时的任意执行点、任意时间点获取(get方法)缓存的数据。

Thread的ThreadLocal本地存储内存区相互隔离,并不共享;但是如果ThreadLocal关联的缓存数据为堆对象时,不同的Thread的ThreadLocal关联到同一个堆对象,这个时候如果有修改操作不是线程安全的。

2.ThreadLocal实现的原理

Thread内部有一个类型为ThreadLocalMap的threadLocals字段,用于存储线程的ThreadLocal数据。每个Thread线程对象都存在一个ThreadLocalMap。

ThreadLocalMap本质上是一个哈希表,采用开放地址法实现,在使用过程中会出现Entry数组扩缩容。

ThreadLocalMap是ThreadLocal的内部类,不能直接使用,只能使用ThreadLocal的api方法。

public class ThreadLocal {
    public T get() {
        #获取当前线程Thread的ThreadLocal
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        // 其他操作
    }

    ThreadLocalMap getMap(Thread t) {    
        return t.threadLocals; 
    }
}

3.使用ThreadLocal的注意事项

static class Entry extends WeakReference>

ThreadLocalMap的Entry为弱引用,方便JVM能自动回收ThreadLocal对象,在方法执行完成后,当ThreadLocal对象不存在强引用时,JVM在接下来出现的第一次gc时会自动回收ThreadLocal对象。

虽然通过弱引用Entry.k指向的ThreadLocal对象能自动回收,但是Entry.value指向的数据对象并不会自动回收,当Entry.k为null时,后边如果调用了这个ThreadLocal的get,set方法时会触发移除Entry对象。

Thread保持执行时,Entry对象被Thread强引用,Entry.value也会强引用数据对象,也就是说只要Entry对象不从ThreadLocalMap中移除,Entry对象和Entry.valude指向的数据对象就会被Thread强引用,都是到根可达的,就不会被JVM回收。

Thread执行退出后相关的ThreadLocalMap,ThreadLocal和数据对象都会被JVM回收;线程池中的线程生命周期同JVM一样,ThreadLocal使用不当会导致内存泄露。

当ThreadLocal缓存数据不在使用时一定要使用ThreadLocal.remove从ThreadLocalMap中移除,让JVM能回收这些内存。

 

4.ThreadLocal的使用场景

经典的使用场景是连接管理,一个线程持有一个连接,不需要通过参数传递就能在不同的方法中使用这个连接,不同的线程使用不同的连接,不需要加锁同步,提高并发性能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/306796.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号