La fermeture de thread adopte généralement les trois méthodes suivantes :
Fermeture de thread ad hoc : implémentation du contrôle du programme, pire, ignorer
Fermeture de pile : variables locales, pas de problèmes de concurrence
Fermeture de thread ThreadLocal : une méthode de fermeture particulièrement efficace
La méthode 2 est la plus couramment utilisée. Les variables sont définies dans l'interface. Cet article explique principalement la méthode 3. Le projet SpringBoot implémente la fermeture de thread ThreadLocal via des filtres et des intercepteurs personnalisés. Implémentez l'interface Filter pour personnaliser le filtre et héritez du HandlerInterceptorAdapter pour personnaliser l'intercepteur.
/** * <p>自定义RequestHolder</p></p> * * @Author zjq * @Date 2021/12 */ public class RequestHolder { private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>(); public static void set(Long id) { requestHolder.set(id); } public static Long get() { return requestHolder.get(); } public static void remove() { requestHolder.remove(); } }
L'intercepteur personnalisé hérite de l'interface Filter et implémente la méthode ThredLocal.add()
/** * <p>自定义过滤器</p> * * @Author zjq * @Date 2021/12/7 */ @Slf4j public class HttpFilter implements Filter { /** * 为Filter初始化 提供支持 * * @param filterConfig * @throws ServletException */ @Override public void init(FilterConfig filterConfig) throws ServletException { } /** * 拦截到要执行的请求时,doFilter就会执行。这里我们可以写对请求和响应的预处理。 * FilterChain把请求和响应传递给下一个 Filter处理 * * @param servletRequest * @param servletResponse * @param filterChain * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //把普通servlet强转成httpServlet HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; Long threadId = Thread.currentThread().getId(); log.info("do filter,threadId:{} servletPath:{}", threadId, httpServletRequest.getServletPath()); //把当前线程id放入requestHolder RequestHolder.set(threadId); //放行 filterChain.doFilter(httpServletRequest, servletResponse); } /** * Filter 实例销毁前的准备工作 */ @Override public void destroy() { } }
Interception personnalisée Le contrôleur supprime le contenu de ThredLocal après que le thread soit utilisé pour éviter un débordement de mémoire
/** * <p>自定义拦截器</p> * * @Author zjq * @Date 2021/12/7 */ @Slf4j public class HttpInterceptor extends HandlerInterceptorAdapter { /** * 拦截处理程序的执行。在 HandlerMapping 确定合适的处理程序对象之后,在 HandlerAdapter 调用处理程序之前调用。 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("preHandle执行。。。"); return true; } /** * 请求处理完成后(渲染视图后)的回调。将在处理程序执行的任何结果上调用,从而允许进行适当的资源清理。 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { RequestHolder.remove(); log.info("afterCompletion执行。。。"); return; } }
/** * * @author zjq */ @SpringBootApplication public class Application extends WebMvcConfigurationSupport { public static void main(String[] args) { SpringApplication.run(ConcurrencyApplication.class, args); } /** * 自定义过滤器 * @return */ @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new HttpFilter()); //设置自定义过滤器拦截的url filterRegistrationBean.addUrlPatterns("/threadLocal/*"); return filterRegistrationBean; } /** * 定义自定义拦截器原先需要继承WebMvcConfigurerAdapter * SpringBoot2.0后WebMvcConfigurerAdapter被定义成过时了,推荐使用继承WebMvcConfigurationSupport * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**"); } }
/** * ThreadLocal测试controller * @author zjq */ @Controller @RequestMapping("/threadLocal") public class ThreadLocalController { @RequestMapping("/test") @ResponseBody public Long test() { return RequestHolder.get(); } }
Accédez à l'interface appelante http://localhost:8080 /threadLocal/test, la sortie de la console est la suivante :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!