ThreadLocal

  1. 什么是ThreadLocal?
    解决多线程并发时访问共享变量的问题,每个线程维护一个副本,互相之间隔离,但是同一线程不同方法和类之间共享
  2. 如何使用?
    一般都会声明成一个静态变量
static ThreadLocal<Object> thread = new ThreadLocal<>();

常用方法:
set()
get()
remove()

原理:
ThreadLocal 内部有一个ThreadLocalMap对象,这个对象是一个Entry类型的数组,并且是弱引用,key是

static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;
    // key为一个ThreadLocal对象,v就是我们要在线程之间隔离的对象
    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

key是ThreadLocal本身,value是要存储的数据
探究一下几个方法的实现

  1. 拿到当前线程,当前线程作为参数,getMap方法拿到当前线程的threadLocals参数
    这个threadLocals其实就是一个ThreadLocal.ThreadLocalMap对象, 最终拿到的就是每个线程内部的
    ThreadLocalMap
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/33b50c070dc54104befcecf453eeedac.png

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

在这里插入图片描述

ThreadLocal本身作为key,在set()方法内部,根据每个线程来计算不同的Entry数组的下标来存储,如图所,hashCode和长度-1做与运算类似于HashMap的寻址方式,减少哈希冲突
在这里插入图片描述

get()方法同理
在这里插入图片描述
在这里插入图片描述

remove()方法如图
在这里插入图片描述

  1. 内存泄露问题
    很多人都说是弱引用导致的,其实不然
    弱引用: 如果一个对象只有弱引用,下一次GC会回收

下图,使用强引用,ThreadLocalRef被回收,CurrentThreadRef没有回收,那么Entry存在强引用,ThreadLocal也不会被回收
在这里插入图片描述
弱引用:
ThreadLocal被回收了,Entry中会存在一个key位null,value不空的数组,造成内存泄漏,因此不管是强引用还是弱引用都会存在内存泄漏,每次使用完要调用remove(),手动清除
在这里插入图片描述

  1. ThreadLocal与Synchronized的区别
    ThreadLocal其实是与线程绑定的一个变量。ThreadLocal和Synchonized都用于解决多线程并发访问。

但是ThreadLocal与synchronized有本质的区别:

1、Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

2、Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本

,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。

而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

  1. 简单使用
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值