ThreadLocal是线程私有的局部变量存储容器,可以理解成每个线程都有自己专属的存储容器,用来存储线程私有变量。ThreadLocal 在日常开发框架中应用广泛,但用不好也会出现各种问题,本文就此讲解一下。
ThreadLocal 的常见应用场景有两种:
public class UserProfileThread {
private static ThreadLocal<UserProfile> USER_PROFILE_TL =new ThreadLocal<>();
public static void setUserProfile(UserProfile userProfile){
USER_PROFILE_TL.set(userProfile);
}
public static UserProfile getUserProfile() {
return USER_PROFILE_TL.get();
}
public static String getCurrentUser() {
return Optional.ofNullable(USER_PROFILE_TL.get())
.map(UserProfile::getUid)
.orElse(UserProfile.ANONYMOUS_USER);
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
UserProfile userProfile = null;
// ... 验证和获取用户信息 userProfile
UserProfileThread.setUserProfile(userProfile);
filterChain.doFilter(servletRequest, servletResponse);
}
//获取当前用户
String uid=UserProfileThread.getCurrentUser();
//获取当前用户对象
UserProfile user=UserProfileThread.getUserProfile();
public class ThreadLocal<T> {
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
// 省略其他方法
}
public class Thread implements Runnable {
ThreadLocal.ThreadLocalMap threadLocals = null;
//省略其他
}