并发编程-ThreadLocal

ThreadLocal

  1. 什么是ThreadLocal?
    ThreadLocal 是线程本地变量类,在多线程并行执行过程中,将变量存储在ThreadLocal中,每个线程中都有独立的变量,因此不会出现线程安全问题。

  2. 应用举例
    解决线程安全问题:例如每个线程都绑定一个数据库连接,避免多个线程访问同一个数据库连接。比如我们为每一个线程绑定一个SqlSession(核心思想就是为每个线程分配一个资源)。
    跨函数参数传递(共享信息):同一个线程,跨类,跨方法传递参数的时候可以使用ThreadLocal。

  3. 关于ThreadLocal
    1)一个线程只能有一个ThreadLocal吗?
    首先我们看到Thread里面,有一个ThreadLocalMap,可以看到再java1.8之后,每个线程都有自己的ThreadLocalMap。在JDK1.8之前是一个全局的ThreadLocalMap。
    在这里插入图片描述
    在这里插入图片描述

2)ThreadLocalMap 里面可以明显的看到是一个数组用于存储多个Entry
在这里插入图片描述
我们看ThreadLocal的源码可以发现是这样一个流程:
1)我们new 一个ThreadLocal 。
2)ThreadLocal.set() 的时候完成了 ThreadLocal 与当前线程的绑定(获取当前线程,然后往当前线程的ThreadLocalMap存放数据)。
3)最终执行的是ThreadLocalMap.set方法。
在这里插入图片描述
如果没有初始化, 还需要调用createMap方法(延迟初始化):
在这里插入图片描述
ThreadLocalMap里面的set方法:
在这里插入图片描述
关于ThreadLocalMap的哈希探测可以参考此文
这篇文章写的非常的详细,更多的展示了源码的细节
4. Entry 的 Key 为什么需要使用弱引用?如果是强引用会造成什么问题?
因为弱引用在GC回收时会被回收,如果使用强引用,我们某个方法里面创建了一个ThreadLocal,我们肯定使用了new关键字,这个时候是强引用,如果这个方法结束,对于这个方法的强引用解除了。但是在ThreadMap里面还存在引用,如果是软引用则在下一次垃圾回收的时候就会被回收。
在这里插入图片描述

如果我们Entry里面使用强引用就会造成内存泄漏,就比如是一个线程池,这个时候线程的生命周期会很长,在上一次执行任务用到的ThreadLocal已经是垃圾了,不会被再使用,但是如果key是强引用导致始终无法被回收掉。这样的话有资源一直回收不掉,堆积后最终就会OOM内存溢出。所以使用了弱引用进行包装源码如下:

static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}
  1. 使用案例(持续补充)
    1)传递共享参数
// 实现 executeOne 和 executeTwo 方法共享
public class DemoTask {
    private ThreadLocal threadLocal;
    public void executeOne() {
        System.out.println(threadLocal.get().toString());
    }
    public void executeTwo() {
        System.out.println(threadLocal.get().toString());
    }
    public static void main(String[] args) {
        ThreadLocal<String> st = new ThreadLocal<>();
        st.set("liyong jiayou");
        DemoTask demoTask = new DemoTask();
        demoTask.threadLocal = st;
        demoTask.executeOne();
        demoTask.executeTwo();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值