【学习笔记】深入理解ThreadLocal(2)

简介: 【学习笔记】深入理解ThreadLocal

三 案例

目录结构:

屏幕快照 2022-05-10 下午12.58.46.png

HttpFilter.java

package com.lyy.threadlocal.config;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Slf4j
public class HttpFilter implements Filter {
//初始化需要做的事情
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    //核心操作在这个里面
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
//        request.getSession().getAttribute("user");
        System.out.println("do filter:"+Thread.currentThread().getId()+":"+request.getServletPath());
        RequestHolder.add(Thread.currentThread().getId());
        //让这个请求完,,同时做下一步处理
        filterChain.doFilter(servletRequest,servletResponse);
    }
    //不再使用的时候做的事情
    @Override
    public void destroy() {
    }
}

HttpInterceptor.java

package com.lyy.threadlocal.config;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HttpInterceptor extends HandlerInterceptorAdapter {
    //接口处理之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle:");
        return true;
    }
    //接口处理之后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        RequestHolder.remove();
       System.out.println("afterCompletion");
        return;
    }
}

RequestHolder.java

package com.lyy.threadlocal.config;
public class RequestHolder {
    private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();//
    //提供方法传递数据
    public static void add(Long id){
        requestHolder.set(id);
    }
    public static Long getId(){
        //传入了当前线程的ID,到底层Map里面去取
        return requestHolder.get();
    }
    //移除变量信息,否则会造成逸出,导致内容永远不会释放掉
    public static void remove(){
        requestHolder.remove();
    }
}

ThreadLocalController.java

package com.lyy.threadlocal.controller;
import com.lyy.threadlocal.config.RequestHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/thredLocal")
public class ThreadLocalController {
    @RequestMapping("test")
    @ResponseBody
    public Long test(){
        return RequestHolder.getId();
    }
}

ThreadlocalDemoApplication.java

package com.lyy.threadlocal;
import com.lyy.threadlocal.config.HttpFilter;
import com.lyy.threadlocal.config.HttpInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@SpringBootApplication
public class ThreadlocalDemoApplication extends WebMvcConfigurerAdapter {
    public static void main(String[] args) {
        SpringApplication.run(ThreadlocalDemoApplication.class, args);
    }
    @Bean
    public FilterRegistrationBean httpFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new HttpFilter());
        registrationBean.addUrlPatterns("/thredLocal/*");
        return registrationBean;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/**");
    }
}

屏幕快照 2022-05-10 下午1.00.00.png

四 总结


1、ThreadLocal是通过每个线程单独一份存储空间,每个ThreadLocal只能保存一个变量副本。

2、相比于Synchronized,ThreadLocal具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问到想要的值,很好的实现了线程封闭。

3、每次使用完ThreadLocal,都调用它的remove()方法,清除数据,避免内存泄漏的风险

4、通过上面的源码分析,我们也可以看到大神在写代码的时候会考虑到整体实现的方方面面,一些逻辑上的处理是真严谨的,我们在看源代码的时候不能只是做了解,也要看到别人实现功能后面的目的。


源码地址:https://github.com/839022478/other/tree/master/threadlocal_demo


目录
相关文章
|
5月前
|
存储 Java
ThreadLocal应用及理解
ThreadLocal应用及理解
49 10
|
缓存 安全 Java
浅谈ThreadLocal
浅谈ThreadLocal
153 0
|
存储 SQL Java
ThreadLocal的其他应用
request对象跟PageHelper
105 0
|
Java
ThreadLocal笔记
ThreadLocal笔记
209 0
ThreadLocal笔记
|
存储 前端开发 Java
ThreadLocal学习笔记(一)
ThreadLocal学习笔记(一)
ThreadLocal学习笔记(一)
|
存储 Java
ThreadLocal相关使用
ThreadLocal相关使用
199 0
ThreadLocal相关使用
|
存储 Java
ThreadLocal理解
ThreadLocal理解
295 0
ThreadLocal理解
|
存储 Java API
【学习笔记】深入理解ThreadLocal(1)
【学习笔记】深入理解ThreadLocal
107 0
【学习笔记】深入理解ThreadLocal(1)
|
存储 安全 Java
我把 ThreadLocal 能问的,都写了(上)
我把 ThreadLocal 能问的,都写了(上)
我把 ThreadLocal 能问的,都写了(上)