Javaマルチスレッド(4)のスレッド閉鎖


スレッド閉鎖:オブジェクトを1つのスレッドにカプセル化します.

スレッドを閉じる方法:

  • ad-hocスレッド閉鎖:プログラム制御、最悪、ゆらゆら;
  • スタック閉鎖:ローカル変数、同時問題なし(グローバル変数、スレッドセキュリティ問題を引き起こしやすい)
  • TreadLocalスレッド閉鎖:特に良い閉鎖方法.

  • 私たちが普段書いているコードは、スレッドセキュリティの問題がなく、スタックが閉鎖されているためです.
    TreadLocalの使用:
    1.requestHolderの作成
    package com.liuhy.test.testapplication.trhreadlocal;
    
    import sun.rmi.runtime.Log;
    
    /**
     * @Auther: liuhy
     * @Date: 2018/11/26 17:33
     */
    public class RequestHolder {
    
        private final static ThreadLocal requestHolder =  new ThreadLocal<>();
    
        public static void add(Long id){
            requestHolder.set(id);
        }
    
        public static Long getId(){
            return requestHolder.get();
        }
    
        public static void remove(){
            requestHolder.remove();
        }
    
    }
    

    2、filterの作成と追加
    package com.liuhy.test.testapplication.filter;
    
    
    import com.liuhy.test.testapplication.trhreadlocal.RequestHolder;
    import lombok.extern.slf4j.Slf4j;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    /**
     * @Auther: liuhy
     * @Date: 2018/11/26 17:36
     */
    @Slf4j
    public class HttpFileter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //  ServletRequest   HttpServletRequest
            HttpServletRequest request=(HttpServletRequest)servletRequest;
    
            log.info("do filter,{},{}",Thread.currentThread().getId(),request.getServletPath());
            // uri , controller id TreadLocal 
            RequestHolder.add(Thread.currentThread().getId());
            filterChain.doFilter(request,servletResponse);
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
    
    

    3、ブロッキングの追加
    package com.liuhy.test.testapplication.filter;
    
    import com.liuhy.test.testapplication.trhreadlocal.RequestHolder;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @Auther: liuhy
     * @Date: 2018/11/26 17:52
     */
    @Slf4j
    public class HttpInterceptor extends HandlerInterceptorAdapter {
    
        /**
         *  
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            log.info("preHandler");
    
            return super.preHandle(request, response, handler);
        }
    
        /**
         *  
         * @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("afterHandler");
            super.afterCompletion(request, response, handler, ex);
        }
    }
    

     
    4、filter及びIntercepterの登録
    package com.liuhy.test.testapplication;
    
    import com.liuhy.test.testapplication.filter.HttpFileter;
    import com.liuhy.test.testapplication.filter.HttpInterceptor;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * @Auther: liuhy
     * @Date: 2018/11/26 17:56
     */
    @Configuration
    public class Config implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new HttpInterceptor());
        }
    
        @Bean
        public FilterRegistrationBean httpFilter(){
            FilterRegistrationBean registrationBean = new FilterRegistrationBean();
            registrationBean.setFilter(new HttpFileter());
            registrationBean.addUrlPatterns("/threadLocal/*");
            return registrationBean;
        }
    }
    

    5、インスタンスコントローラ使用
    package com.liuhy.test.testapplication.trhreadlocal;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * @Auther: liuhy
     * @Date: 2018/11/26 18:02
     */
    @Controller
    @RequestMapping("/threadLocal")
    public class ThreadLocalController {
    
        @RequestMapping("/test")
        @ResponseBody
        public String getLocal(){
            Long id = RequestHolder.getId();
    
            return "this is ThreadLocal "+id;
        }
    }