基于拦截器的ThreadLoacl自动回收器
一、场景
- 容器t线程池的生命周期和请求的生命周期不同,无法保存请求域的ThreadLocal参数隔离
- 请求域每次都需要手动回收ThreadLocal,暂时不考自定义线程池的解决
- 对于simpleDateFormat、DecimalFormat等线程不安全的类,设置作用域,保证线程安全,同时避免重复创建浪费内存空间
二、 解决方案
- 基于拦截器的ThreadLocal回收器
- ThreadLocal自动清理注册
- HTTP请求的标记
@NoArgsConstructor(access = AccessLevel.PRIVATE)public class ThreadLocalCleaner {
private static final List<ThreadLocal<?>> CONTAINER = Lists.newArrayList();
public static void register(ThreadLocal<?>... threadLocal) {
if(ArrayUtils.isNotEmpty(threadLocal)) {
// 可以优化
CONTAINER.addAll(Arrays.asList(threadLocal));
}
}
public static void clear() {
CONTAINER.forEach(ThreadLocal::remove);
}
}
public class ThreadLocalInterceptor extends HandlerInterceptorAdapter {
/**
* 是否是从http进入的线程
*/
private static final ThreadLocal<Boolean> IS_HTTP_REQUEST = new ThreadLocal<>();
static {
ThreadLocalCleaner.register(IS_HTTP_REQUEST);
}
public static boolean isHttpReqThread() {
return Boolean.TRUE.equals(IS_HTTP_REQUEST.get());
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//thread local set
IS_HTTP_REQUEST.set(Boolean.TRUE);
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//thread local remove
ThreadLocalCleaner.clear();
super.afterCompletion(request, response, handler, ex);
}
}
以上是 基于拦截器的ThreadLoacl自动回收器 的全部内容, 来源链接: utcz.com/z/515854.html