ThreadLocal为线程提供一个线程级别的储物柜,可以往里面存数据,取数据。数据是专属于线程的。
而局部变量,也是专属于线程的。这样来看,两者似乎功能上是一样的,也确实是一样的。
不过局部变量只能通过显示传参的方式让参数到达某一个方法。而ThreadLocal可以直接设置为一个静态变量,各个线程共享。这样可以实现隐式传输参数。(特别是一些与业务无关但却有用的参数)
ThreadLocal类似于银行,每个人都可以往里面存数据,通过线程来辨别不同的用户,每个线程就相当于ThreadLocal的一个用户。
也就是说:相比于局部变量。ThreadLocal的优点就是可以在任意地方获取一些专属于当前线程的数据。
使用例子:定义一个全局的ThreadLocal,每当用户登录的时候,都会在接口校验登录状态成功之后就把当前登录的用户的ID存进去,这样你就可以在任意一个方法内去使用当前用户的ID。
一般可以考虑使用ThreadLocal来实现如下功能:
1.统计接口请求的持续时间
2.实现请求的RPC日志。
3.如果接口需要登录才能使用,可以用于存储当前请求用户的用户信息。
ThreadLocal的实现是通过一个map来实现的,每当有线程往里面存东西,都会用当前线程的线程id作为key去存储数据,这样下次获取的时候也是根据当前线程的线程id来获取,这样就可以确保数据专属于线程。
验证一下:
import java.util.Random;
public class Test implements Runnable{
private static final ThreadLocal<Long> threadName=new ThreadLocal<>();
private static final ThreadLocal<Long> startTime=new ThreadLocal<>();
@Override
public void run() {
startTime.set(System.currentTimeMillis());
threadName.set(Thread.currentThread().getId());
System.out.println(startTime.get()+" "+threadName.get());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(startTime.get()+" "+threadName.get());
}
public static void main(String[] args) {
Test test=new Test();
for(int i=0;i<5;i++){
Thread thread=new Thread(test,"thread"+i);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}