`

从ThreadLocal引出的联想

阅读更多

 

    背景:

      最近做服务化拆分,拆分公共登录的拦截器,看到一些ThreadLocal的使用场景。分享下由下面一段拦截器代码引发的一些ThreadLocal使用场景和面试题的思考。

   

    介绍:

      关于ThreadLocal可以参照http://labreeze.iteye.com/blog/2159531

 

      如果把这个拦截器放在最前面,后面如果需要用到request则直接调用WebCommonConstant.requestTL.get

    就可以直接获取到request,省了在很多方法里面传参问题,非常方便。

 

public class WebPreLoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        WebCommonConstant.requestTL.set(request);
        WebCommonConstant.responseTL.set(response);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        WebCommonConstant.requestTL.remove();
        WebCommonConstant.responseTL.remove();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

 

   由此联想到一些经常被问到的面试题,顺便在这里总结一下

 

    1. Spring bean默认是单例的,如何保证线程安全?

        以前对于这种问题我觉得比较晕,现在我觉得以前可以分成两个方面来回答。

        a) 如果Spring bean是无状态的,本身就是线程安全的,无需保证。

        b) 如果Spring bean 状态是有状态的,如某个bean里面一个含有一个有状态的属性,则把这个属性用ThreadLocal封装起来,每个线程拥有自己的变量这样就隔离了多线程的问题了。使用这种方式的Spring内部bean有(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)。

     

    示例demo : 

public class A {
  ThreadLocal<Var> localMap = new ThreadLocal<Var>();

  public void pre() {
  	Var var =localMap.get();
  	if(null == var) {
  		var = new Var();
  	}
  	localMap.set(var);
  }

  public void test() {
  	Var var = localMap.get();
  	var.xx();
  }

  public void post() {
  	localMap.remove();
  }
}

 

 

    2. ThreadLocal与同步锁的关系?

    ThreadLocal 其实相当于独享变量,避免了锁竞争。但是需要大量的创建对象占用内存。ThreadLocal相当于以空间换时间,锁同步则以时间换空间。

 

    3. ThreadLocal有哪些使用场景?

      a) 避免方法传入公共的属性,如request,response这些

      b) 避免线程安全问题。

 

  

 

   

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics