本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!
今天是我在掘金的第二篇文章,感谢阅读,并希望以后持续关注,我会输出更多技术干货,我们共同进步!
以后可能会分为几大专题,类似于并发专题,源码专题,面试专题等(只会分享干货)。
请出今天的主角: ThreadLocal
见字如面
ThreadLocal 很好理解:Thread(线程)、local(本地)
那么你大概就明白了,这个东西是属于本地线程。可以理解map本地缓存之类的,但是这里面有thread,并非共享数据,而是每个线程都有自己的一个空间,互不影响。那么接下来通过具体业务场景了解其背后的用法:
场景介绍
- ThreadLocal 用作保存每个线程独享的对象,为每个线程都创建一个副本,这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本,确保了线程安全。
该场景的具体分析可以点击查看:ThreadLocal 使用场景02
- 用作每个线程内需要独立保存信息,以便供其他方法更方便地获取该信息的场景。每个线程获取到的信息可能都是不一样的,前面执行的方法保存了信息后,后续方法可以通过 ThreadLocal 直接获取到,避免了传参,类似于全局变量的概念。该场景在业务中应用可能更广泛些,本篇文章主要介绍该场景的使用,第一种场景的链接为:ThreadLocal 使用场景02。接下来通过一副图深入了解 :
接下来看代码演示
代码演示
/**
* 变量存储
* @author yn
* @date 2021/7/11
*/
public class LocalContext {
//初始化 ThreadLocal 将用户信息装进Local
private static final ThreadLocal<Node> LOCAL = new InheritableThreadLocal<Node>(){
@Override
protected Node initialValue() {
return new Node();
}
};
/**
* 将userID装进本地缓存
* @param userId
*/
public static void setUserId(Integer userId){
LOCAL.get().setUserId(userId);
}
/**
* 获取用户
* @param userId
*/
public static Integer getUserId(){
return LOCAL.get().getUserId();
}
/**
* 清除本地变量
*/
public static void remove(){
LOCAL.remove();
}
....省略其他信息
}
/**
* 定义用户
* @author yn
* @date 2021/7/11
*/
@Data
public static class Node {
private Integer userId;
private String openId;
private String mobile;
private String appId;
public Node(){
this.userId = 0;
this.openId = "";
this.mobile = "";
this.appId = "";
}
}
复制代码
以上就是操作ThreadLocal的一个简单工具类,是不是感觉有点像redis、map之类。
简单原理描述
首先 ThreadLocal 是一个泛型类,保证可以接受任何类型的对象。
因为一个线程内可以存在多个 ThreadLocal 对象,所以其实是 ThreadLocal 内部维护了一个 Map ,这个 Map 不是直接使用的 HashMap ,而是 ThreadLocal 实现的一个叫做 ThreadLocalMap 的静态内部类。而我们使用的 get()、set() 方法其实都是调用了这个ThreadLocalMap类对应的 get()、set() 方法。
更深的我们先不讨论,后面我会把它放到源码专题做出详细讨论。感谢大家的阅读,希望对你有帮助。欢迎大家点赞、评论、转发。
弦外之音
最近全国大部门地区暴雨来袭,希望大家出门带好雨具,注意安全。话说回来,北京说好的暴雨呢,各种防范措施都已就绪,怎么还不见下呢。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END