ThreadLocal 简单介绍

147 阅读1分钟

ThreadLocal 简介

1.ThreadLoal是什么

ThreadLocal被称为本地线程变量。也就是说ThreadLocal填充的是本地线程的变量,它对于其他线程是封闭隔离的。

ThreadLocal对于每个线程是相互隔离的,不被别的线程共享

ThreadLocal本身是一个全局变量,但是不同的线程对同一个ThreadLocal对象通过get()和set()可以获取到不同的值。

static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println(threadLocal.get());
            threadLocal.set(1);
            System.out.println(threadLocal.get());
        });
        Thread t2= new Thread(() -> {
            System.out.println(threadLocal.get());
            threadLocal.set(2);
            System.out.println(threadLocal.get());

        });
        t1.start();
        t1.join();
        t2.start();
   }
/*
null
1
null
2

应用场景

底层实现原理

image-20220310090006820

当我们进行set(value)操作的时间

会调用currentThread()方法获取当前线程

每个线程都一个变量threadLocals(ThreadLocalMap类型). 他是一个map类型的

以threadlocal对象为键 , value对象为值 放着threadlocals对象中。

这样当线程thread1以调用set()方法的时候,会找到thread1的threadLocals。

同理,thread2也会找到自己的threadLocals

这两个threadLocals是不一样的,所以可以实现隔离。

使用ThreadLocal会存在内存泄露问题。

image-20220310091204993

ThreadLocalMap中 key为ThreadLocal,是弱引用,而val是强引用。在垃圾回收时,如果ThreadLocal没有被外部强引用的化,就会被垃圾回收器清理。然而由于val是强引用的,所以val是不会被清理。这样我们就不能通过key获取到这个val值,导致val值永远不会被清理掉。所以造成了内存泄露问题。所以在使用完ThrealLcal方法后,最好手动调用remove方法。