ThreadLocal的底层原理是什么 使用场景有哪些【面试题详解】

今天爱分享给大家带来ThreadLocal的底层原理,希望能帮助到大家。

ThreadLocal,该类提供了线程局部 (thread-local) 变量,ThreadLocal会为每个线程创建变量的副本,线程之间互不影响,这样就不存在线程安全问题。在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals用来存储实际的变量副本容器, 键值为当前ThreadLocal变量,value为变量副本。
1)初始时,在Thread的threadLocals为空,调用ThreadLocal变量调用get()方法或者set()方法,就会对threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals中。
2)然后在当前线程里面,如果要使用副本变量,就可以通过get方法在threadLocals里面查找。

概括:
ThreadLocal,很多地方叫做线程本地变量,因为ThreadLocal在每个线程中对该变量会创建一个副本,即每个线程内部都会有一个该变量,且在线程内部任何地方都可以使用,线程之间互不影响,这样一来就不存在线程安全问题,也不会严重影响程序执行性能。在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。ThreadLocal相当于一个工具包,提供了操作该容器的方法,如get、set、remove等。在进行get之前,必须先set,否则会报空指针异常;否则必须重写initialValue()方法。
场景:数据库连接和session管理
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。
每个线程都保持对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
使用:
set(obj):向当前线程中存储数据 get():获取当前线程中的数据 remove():删除当前线程中的数据

实现原理:
ThreadLocal并不维护ThreadLocalMap(ThreadLocalMap是Thread的)并不是一个存储数据的容器,它只是相当于一个工具包,提供了操作该容器的方法,如get、set、remove等。而ThreadLocal内部类ThreadLocalMap才是存储数据的容器,并且该容器由Thread维护。 每一个Thread对象均含有一个ThreadLocalMap类型的成员变量threadLocals,它存储本线程中所有ThreadLocal对象及其对应的值( ThreadLocalMap 是个弱引用类,内部 一个Entry由ThreadLocal对象和Object构成,
为什么要用弱引用呢?
如果是直接new一个对象的话,使用完之后设置为null后才能被垃圾收集器清理,如果为弱引用,使用完后垃圾收集器自动清理key,程序员不用再关注指针。)
操作细节
进行set,get等操作都是首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap对象。再以当前ThreadLocal对象为key ,再做相应的处理。
内存泄露问题
在ThreadLocalMap中,只有key是弱引用,value仍然是一个强引用。
每次操作set、get、remove操作时,ThreadLocal都会将key为null的Entry删除,从而避免内存泄漏。
当然,当 如果一个线程运行周期较长,而且将一个大对象放入LocalThreadMap后便不再调用set、get、remove方法,此时该仍然可能会导致内存泄漏。 这个问题确实存在,没办法通过ThreadLocal解决,而是需要程序员在完成ThreadLocal的使用后要养成手动调用remove的习惯,从而避免内存泄漏。

使用场景
Web系统Session的存储
当请求到来时,可以将当前Session信息存储在ThreadLocal中,在请求处理过程中可以随时使用Session信息,每个请求之间的Session信息互不影响。当请求处理完成后通过remove方法将当前Session信息清除即可。

人已赞赏
Java

synchronized 和 volatile 的区别是什么?【面试题详解】

2020-11-6 16:01:49

Java

ThreadLocal是如何为每个线程创建变量的副本的【面试题详解】

2020-11-6 16:04:28

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧