ThreadLocal【Java】

来自智得网
跳转至: 导航、​ 搜索

简介

ThreadLocal是指线程变量,这些变量是线程私有的,不和其他线程共享,所以不存在线程安全的问题。和一般同步机制使用锁等方式进行进行临界区的互斥不同,ThreadLocal通过拷贝变量副本来进行数据隔离。

原理

ThreadLocal存储结构图

存储结构

在JDK1.8之后,每个Thread会关联一个Map,称为ThreadLocalMap,存放这个线程的ThreadLocal变量,这个ThreadLocalMap的Key就是ThreadLocal变量。

在读写ThreadLocal的时候,首先获取当前线程,然后当前线程可以关联到ThreadLocalMap,再通过ThreadLocal对Map进行读写。

在JDK1.8之前的版本中,每个ThreadLocal都关联一个单独的map对象,map的Key是当前线程,value是ThreadLocal的值。

内存泄漏

ThreadLocalMap中的Key到ThreadLocal变量的引用是弱引用,弱引用在垃圾回收的时候会被优先回收。

因为ThreadLocal的生命周期和ThreadLocalMap的生命周期(即Thread的生命周期)不一致,所以可能会出现ThreadLocal被垃圾回收,但是ThreadLocalMap中的Value值依然存在,就会造成内存泄漏。

为了避免内存泄漏,在每次使用ThreadLocal变量之后,最好手动清理,不仅仅可以避免内存泄漏,也减少了线程共享(例如线程池)时候的可能引发的逻辑错误。

应用

ThreadLocal的应用场景如下:

  • Session会话信息
  • 数据库链接等信息
  • 线程不安全的工具类,例如Random,SimpleDateFormat。