ThreadLocal,线程本地变量,作为多线程编程中很重要的一个组件,有很多的应用。比如数据库连接池的实现,以及自定义分布式锁的实现等。今天,就来介绍一下ThreadLocal的内部原理以及不规范的使用会导致的问题--内存泄漏。
本文的内容结构如下:
- ThreadLocal 的原理和源码
- ThreadLocal带来的问题
- ThreadLocal的实例应用 - 基于Redis的分布式自旋锁
一、ThreadLocal
- ThreadLocal核心方法
说到一个类,必然先查看这个类的构造方式。ThreadLocal采用函数式编程,定义一个静态方法,传入一个函数,从而构造ThreadLocal。例如:
ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() ->
{
return new SimpleDateFormat("yyyy-MM-dd");
});
// 或者简写为
ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"))
ThreadLocal中最核心的两个方法,get 和 set。下面从源码角度分别对这两个方法进行解析。
public T get() {
Thread t = Thread.currentThread(); // 获取当前线程
ThreadLocalMap map = getMap(t); // ThreadLocalMap,ThreadLocal中的重要的内部类
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue(); // 否则直接设置初始值
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);