Java ThreadLocal详解

100 阅读1分钟

1. ThreadLocal 概述

ThreadLocal 的作用是为线程提供独立的私有变量,每个 Thread 都会有一个私有的 ThreadLocalMap,同一个 ThreadLocal 对象会作为 key 值在线程各自私有的 ThreadLocalMap 中指向不同的 value。

ThreadLocal 为线程变量,ThreadLocal中变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量,所以也可以称为线程局部变量,同一个ThreadLocal所包含的对象,在不同的Thread中有不同的副本。

2. 数据结构

ThreadLocal 中 最为重要的结构为 ThreadLocalMap。ThreadLocalMap是ThreadLocal类的静态内部类,key 为 ThreadLocal 变量,value为用户传入的值。

image.png

2. ThreadLocal 使用

public class ThreadLocalDemo {

    //创建ThreadLocal变量
    static ThreadLocal<String> localParam = new ThreadLocal<>();

    public static void main(String[] args) {
        //创建2个线程,分别设置不同的值
        new Thread(()->{
            localParam.set("hello java");
            //打印当前线程本地内存中的localParam变量的值
            System.out.println(
            Thread.currentThread().getName() + ":" + localParam.get()); // hello java
        },"T1").start();
        new Thread(()->{
            localParam.set("hello web");
            System.out.println(
            Thread.currentThread().getName() + ":" + localParam.get()); // hello web
        },"T2").start();
    }
}

3. ThreadLocal 知识点

  • ThreadLocal 可能会造成内存泄漏,在使⽤了 ThreadLocal对象之后,⼿动调⽤ThreadLocal的remove⽅法,⼿动清楚Entry对象
  • ThreadLocalMap 中 key 指向 ThreadLocal 的链接是弱连接(弱连接在触发GC的时候就会被回收)
  • ThreadLocal经典的应⽤场景就是连接管理(⼀个线程持有⼀个连接,该连接对象可以在不同的⽅法之 间进⾏传递,线程之间不共享同⼀个连接)
  • 线程池慎用 ThreadLocal,可能因为忘记调用remove导致内存泄漏
  • Spring事务在实现的过程中,采用Threadlocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接