1 ThreadLocal是什么?
ThreadLocal,也就是线程本地变量。如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际是操作自己本地内存里面的变量,从而起到线程隔离的作用,避免了线程安全问题。
2 ThreadLocal的使用
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("hello");
System.out.println(threadLocal.get());
3 ThreadLocal有哪些应用场景
1.线程池技术
使用线程池执行多个任务时,为了避免线程间数据冲突,可以使用ThreadLocal存储每个线程独有的数据,这样就可以安全地在多个线程间共享线程池。
2.Web应用程序
在Web应用中,每个请求一般都会被分配到不同的线程处理,ThreadLocal可以用来存储当前请求的上下文信息,列如用户ID、请求时间等,这些信息可以在同一个请求处理过程中多次使用,特别是一个请求嵌套调用许多方法的时候可以使用,但是不同请求之间是相互独立的。
3.数据库连接
在多线程环境下,为了避免每个线程都去创建和销毁数据库连接,可以使用连接池技术。使用ThreadLocal可以将连接池中的数据库连接与当前线程绑定,确保每个线程都能够得到自己独有的数据库连接,避免数据混乱和线程安全问题。
4 ThreadLocal 内存泄露是怎么回事
我们先来分析一下使用ThreadLocal时的内存,我们都知道,在JVM中,栈内存线程私有,存储了对象的引用,堆内存线程共享,存储了对象实例。
所以呢,栈中存储了ThreadLocal、Thread的引用,堆中存储了它们的具体实例。
ThreadLocalMap中使用的 key 为 ThreadLocal 的弱引用。
那么目前问题就来了,弱引用很容易被回收,如果ThreadLocal(ThreadLocalMap的Key)被垃圾回收器回收了,但是ThreadLocalMap生命周期和Thread是一样的,它这时候如果不被回收,就会出现这种情况:ThreadLocalMap的key没了,value还在,这就会造成了内存泄漏问题。
那怎么解决内存泄漏问题呢?
很简单,使用完ThreadLocal后,及时调用remove()方法释放内存空间。
那为什么key还要设计成弱引用?
key设计成弱引用同样是为了防止内存泄漏。
如果key被设计成强引用,如果ThreadLocal Reference被销毁,此时它指向ThreadLoca的强引用就没有了,但是此时key还强引用指向ThreadLoca,就会导致ThreadLocal不能被回收,这时候就发生了内存泄漏的问题。
【温馨提示】
点赞+收藏文章,关注我并私信回复【面试题解析】,即可100%免费领取楼主的所有面试题资料!


