多线程不可避免需要处理状态,处理状态有三种方式:共享可变性、隔离可变性和纯粹不可变。使用ThreadLocal属于隔离可变性的一种方法,但是ThreadLocal使用不当又可能导致内存泄漏,下面简单介绍一下ThreadLocal。
本文基于JDK 1.8
介绍
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g.,a user ID or Transaction ID).
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the {@code ThreadLocal} instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).
核心意思是
ThreadLocal 提供了线程本地的实例。它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都可被回收。
总的来说,ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景。
原理
从set方法入手
1 | public void set(T value) { |
注意事项
防止内存泄露,使用完需要调用ThreadLocal的remove()方法
常用方法
- get() 返回当前线程的此线程局部变量的副本中的值
- 获取当前线程的属性:ThreadLocal.ThreadLocalMap threadLocals (即:一个map)
- map中获取线程存储的K-V Entry键值对
- 返回存储的变量
- set(T value) 将当前线程的此线程局部变量的副本设置为指定的值
- remove() 删除此线程局部变量的当前线程的值
简单代码示例
1 | public class TheadLocalExampleHolder { |