基于拦截器的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

回到顶部