ThreadLocal源码小记

ThreadLocal作用是设置一个线程局部变量,保证该变量线程各隔离。通常使用set方法设值

set方法

在这里插入图片描述

set方法的逻辑是:获取本地线程中的ThreadLocalMap对象,如果不为空则以该ThreadLocal对象为key,想要存储的变量为值进行set。若为空则初始化该线程的ThreadLocalMap对象

初始化ThreadLocalMap

在这里插入图片描述
在这里插入图片描述

在当前线程实例中设置Map属性

get方法

在这里插入图片描述

获取当前线程的ThreadLocalMap,通过当前threadlocl实例为key取值

ThreadLocalMap底层存储逻辑

        /**
         * Set the value associated with key.
         *
         * @param key the thread local object
         * @param value the value to be set
         */
        private void set(ThreadLocal<?> key, Object value) {

            // We don't use a fast path as with get() because it is at
            // least as common to use set() to create new entries as
            // it is to replace existing ones, in which case, a fast
            // path would fail more often than not.

            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);

            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal<?> k = e.get();

                if (k == key) {
                    e.value = value;
                    return;
                }

                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            int sz = ++size;
            if (!cleanSomeSlots(i, sz) && sz >= threshold)
                rehash();
        }

Entry数组存储线程变量,以ThreadLocal实例的hashcode为key,以想要存储的对象为值。如果已存在则覆盖,如果没有则赋值。

使用场景

Mybatis、Hibernate中设计到线程通过数据库连接对象Connection,对其数据进行操作,都会使用ThreadLocal类来保证Java多线程程序访问和数据库数据的一致性问题。

注意事项

ThreadLocal使用结束时一定要记得清除。
在这里插入图片描述

web服务器多采用线程池机制,也就是说线程是可以复用的,所以在每次进入的时候都需要重新进行set操作,或者使用完毕以后及时remove掉。如果不remove还可能会造成内存泄漏。

内存泄漏

线程池中线程不回收,ThreadLocalMap实例也不会回收,而value值是强引用,无法被回收,久而久之就会造成内存泄漏。

这篇文章不错
链接: ThreadLocal底层原理详解.

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值