ThreadLocal

一、ThreadLocal是什么?线程本地变量  数据隔离

  1.ThreadLocal用来存放线程本地变量,提供了一种线程安全的方式,用来避免数据共享(线程变量隔离)。

  ThreadLocal<T>其实是与线程绑定的一个变量

  ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。

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

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

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

  ThreadLocal 提供了线程本地的实例。它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都会被回收。
2.ThreadLocal底层实现原理
3.常用方法
   set() 设置变量
   get() 获取变量
   remove() 移除变量
   initialValue() 返回变量的初始值

二、线程池中使用threadlocal为什么容易造成内存泄漏?(Thread 一直不终结的话,value 对象就会一直存在于内存中,也就导致了内存泄漏。)解决方法:调用remove()方法

  1.ThreadLocal 在没有外部强引用时,发生 GC 时会被回收,那么 ThreadLocalMap 中保存的 key 值就变成了 null,而 Entry 又被 threadLocalMap 对象引用,threadLocalMap 对象又被 Thread 对象所引用,那么当 Thread 一直不终结的话,value 对象就会一直存在于内存中,也就导致了内存泄漏,直至 Thread 被销毁后,才会被回收。

  简单来说,就是ThreadLocalMap中的key被GC回收了,而value值还在内存中。

  2.解决办法:

  1)调用remove方法手动删除threadLocal的数据。

三、ThreadLocal使用场景

  每个线程需要自己独立的实例且该实例需要在多个方法中使用。

  1. 多线程环境中为每一个jdbc分配一个Connection连接,使用ThreadLocal去保存连接,这样就保证了每个线程在自己的连接上操作数据库,不会出现A线程关闭B的Connnection操作。

  2. Web中的session管理时,可以使用ThreadLocal记录每个线程的Session,这样保证每个线程都可以获取自己的session。

  3. 解决线程安全问题,对于需要进行线程隔离的变量,可以使用ThreadLocal存储,确保线程隔离。

  4.Spring 事务管理器采用了 ThreadLocal。

  5.Spring MVC 的 RequestContextHolder 的实现使用了 ThreadLocal。

四、引用类型

引用类型 回收时间 使用场景 生存时间
强引用 从来不会 普通的引用Object o = new Object() JVM停止运行时终止
软引用 当内存不足时 内存敏感的高速缓存 内存不足时终止
弱引用 正常GC时 对象缓存(ThreadLocal等) 垃圾回收后终止
虚引用 正常GC时 跟踪对象被回收的状态 垃圾回收后终止

 

 

 



 

 

 

 

posted @ 2020-04-16 22:25  遇见神龙  阅读(197)  评论(0编辑  收藏  举报