ThreadLocal

179 阅读1分钟
package com.hoolai.lock;

import java.sql.Time;
import java.util.concurrent.TimeUnit;

/**
 *
 *@description:
 
 当触发gc时如果没有强引用指向弱引用时,ThreadLocalMap的key就会被清除,但是value还保存着的。
 如果现在不会被回收的话,就会导致内存泄漏
 *@author: Ksssss(chenlin@hoolai.com)
 *@time: 2020-06-12 19:39
 * 
 */
 
public class ThreadLock {
    private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    private ThreadLocal<Integer> threadLocal2 = new ThreadLocal<>();
    private ThreadLocal<Integer> threadLocal3 = new ThreadLocal<>();

    public void run(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                threadLocal.set(1);
                threadLocal2.set(2);
                threadLocal3.set(3);
                threadLocal = null;
                try {
                    Thread.sleep(3000);
                    threadLocal2=null;
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread y = Thread.currentThread();
                System.gc();
                try {
                    Thread.sleep(3000);
                    int value = threadLocal3.get();
                    System.out.println(value);
                    threadLocal3=null;
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread x = Thread.currentThread();
                System.out.println(x);
            }
        }).start();
    }
    public static void main(String[] args) throws InterruptedException{
        new ThreadLock().run();
        Thread.sleep(100000);
    }
}

threadLocal的set

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

createMap方法

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

Thread对象里面的threadLocals变量

/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

一个线程维护了一个ThreadLocalMap<ThreadLocal,value> 的静态内部类。而我们使用的 get()、set() 方法其实都是调用了这个ThreadLocalMap类对应的 get()、set() 方法。所以一个线程可以维护很多的ThreadLocal对象。