ThreadLocal原理及使用
一、ThreadLocal介绍
- 使用场景:同一个线程共享数据。
- ThreadLocal的作用:实现线程范围内的局部变量,即ThreadLocal在一个线程中是共享的,在不同线程之间是隔离的。
原理:
- 原理:
使用场景:
ThreadLocal内存泄漏如何避免
**注意:**调用remove方法的前提是知道是否使用完,即key值是否已经为空,那么就涉及到弱引用是否为空的判断,java9提供了方便的判断方式,如下图:
- 面试题:
二、ThreadLocal使用
1、创建拦截器,在拦截器中创建一个ThreadLocal对象
package com.furenqiang.gulimall.auth.filiter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyInterceptor implements HandlerInterceptor {
public static ThreadLocal<Object> objectThreadLocal = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
}
2、配置mvc,使自定义拦截器生效
package com.furenqiang.gulimall.auth.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AuthWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry){
//添加拦截器并,作用范围为所有请求
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
3、存储数据,在任意地方都能使用
Object o = MyInterceptor.objectThreadLocal.get();
MyInterceptor.objectThreadLocal.set("yourEntity");
4、如果是异步编排异步执行的任务,线程不一样时,是不能共享ThreadLocal的信息的,所以得在异步编排之前的主线程取得需要的信息
如果要获取request,可使用下面代码:
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
5、案例二:threadlocal获取数据库连接