java八股文面试[多线程]——ThreadLocal底层原理和使用场景

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第1张图片

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第2张图片

源码分析:

ThreadLocal中定义了ThreadLocalMap静态内部类,该内部类中又定义了Entry内部类。

ThreadLocalMap定了 Entry数组。

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第3张图片

Set方法:

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第4张图片

Get方法:

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第5张图片

Thread中定义了两个ThreaLocalMap成员变量:

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第6张图片

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第7张图片

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第8张图片

Spring使用ThreadLocal解决线程安全问题 

我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全的“状态性对象”采用ThreadLocal进行封装,让它们也成为线程安全的“状态性对象”,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。 

一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程,如图
java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第9张图片

这样用户就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有对象所访问的同一ThreadLocal变量都是当前线程所绑定的。

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第10张图片

内存泄漏原因:

ThreadLocal其实是与线程绑定的一个变量,如此就会出现一个问题:如果没有将ThreadLocal内的变量删除(remove)或替换,它的生命周期将会与线程共存。通常线程池中对线程管理都是采用线程复用的方法,在线程池中线程很难结束甚至于永远不会结束,这将意味着线程持续的时间将不可预测,甚至与JVM的生命周期一致。举个例字,如果ThreadLocal中直接或间接包装了集合类或复杂对象,每次在同一个ThreadLocal中取出对象后,再对内容做操作,那么内部的集合类和复杂对象所占用的空间可能会开始持续膨胀。
 

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第11张图片

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第12张图片

java八股文面试[多线程]——ThreadLocal底层原理和使用场景_第13张图片

知识来源:

【并发与线程】ThreadLocal的底层原理_哔哩哔哩_bilibili

【并发与线程】ThreadLocal的原理的使用场景_哔哩哔哩_bilibili

【并发与线程】ThreadLocal内存泄露问题,如何避免_哔哩哔哩_bilibili

史上最全ThreadLocal 详解(一)_倔强的不服的博客-CSDN博客

史上最全ThreadLocal 详解(二)_多个threadlocal_倔强的不服的博客-CSDN博客

你可能感兴趣的:(java八股文,java,面试,开发语言)