什么是TheadLocal
ThreadLocal 是 Java 里一种特殊变量,它是一个线程级别变量,每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞态条件被彻底消除了,在并发模式下是绝对安全的变量。
下面通过例子了解一下ThreadLocal:
/**
* ThreadLocal变量,每个线程都有一个副本,互不干扰
*/
public static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<>();
public static void main(String[] args) throws Exception {
new ThreadLocalDemo().threadLocalTest();
}
public void threadLocalTest() throws Exception {
// 主线程设置值
THREAD_LOCAL.set("wupx");
String v = THREAD_LOCAL.get();
System.out.println("Thread-0线程执行之前," + Thread.currentThread().getName() + "线程取到的值:" + v);
new Thread(new Runnable() {
@Override
public void run() {
String v = THREAD_LOCAL.get();
System.out.println(Thread.currentThread().getName() + "线程取到的值:" + v);
// 设置 threadLocal
THREAD_LOCAL.set("huxy");
v = THREAD_LOCAL.get();
System.out.println("重新设置之后," + Thread.currentThread().getName() + "线程取到的值为:" + v);
System.out.println(Thread.currentThread().getName() + "线程执行结束");
}
}).start();
// 等待所有线程执行结束
Thread.sleep(3000L);
v = THREAD_LOCAL.get();
System.out.println("Thread-0线程执行之后," + Thread.currentThread().getName() + "线程取到的值:" + v);
}
}
这是运行结果: Thread-0线程执行之前,main线程取到的值:wupx Thread-0线程取到的值:null 重新设置之后Thread-0线程取到的值为:huxy Thread-0线程执行结束 Thread-0线程执行之后,main线程取到的值:wupx
ThreadLocal 内存泄露
ThreadLocal在没有外部引用时,发生GC时会被回收,那么ThreadLocalMap中保存的key值就变成了null,而Entry又被threadLocalMap对象引用,threadLocalMap对象又被Thread对象所引用,如果当前Thread运行时间很长的话,例如Thread存活于线程池中,value对象就会一直存在于内存中,就可能会导致内存泄露,直至Thread被销毁后,才会被回收。