`
iaiai
  • 浏览: 2203856 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

理解ThreadLocal

    博客分类:
  • J2EE
 
阅读更多
ThreadLocal是什么

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。

ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。

所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。

ThreadLocal的接口方法

ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:
  • void set(Object value)

  • 设置当前线程的线程局部变量的值。
  • public Object get()

  • 该方法返回当前线程所对应的线程局部变量。
  • public void remove()

  • 将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
  • protected Object initialValue()

  • 返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

    值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

    ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。


    用ThreadLocal 管理用户session

    很多项目中需要在代码中使用当前登录用户的信息,但是又不方便把保存用户信息的session对象传来传去,这种情况下,就可以考虑使用 ThreadLocal。

    ThreadLocal是一个依附于本地线程的变量,按照我的理解,每次对服务器请求,都会使用到一个线程,ThreadLocal的作用就是在这个线程的使用过程中只为这个线程所用。

    说说具体如何管理用户session。

    现在SSH框架用的比较多,有时在DAO层中需要用到当前用户信息,我们首先定义保存在HttpSession中的用户类,可以是你的用户model,也可以是嵌套了model的包装类,我这里叫UserSession。

    在登录方法里将上面定义的用户类对象放入HttpSession中,即:
    session.setAttribute("UserSession", userSession);


    写一个用于检验用户的filter,并在web.xml中配置,目的是判断用户有没有登录以及登录用户有没有对要访问链接的权限等,每次请求经过filter时如果HttpSession中的UserSession对象存在的话重新设置一下:
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {  
        HttpServletRequest request = (HttpServletRequest)req;  
      
        UserSession userSession = (UserSession)request.getSession().getAttribute("UserSession");  
      
        if (userSession == null) {  
            //跳转登录页面  
            ...  
        } else {  
            request.getSession().setAttribute("UserSession", userSession);  
            filterChain.doFilter(req, res);  
        }  
    }
    


    然后创建一个类,用于存放ThreadLocal的静态变量:
    public class SystemSession {  
      
        private static ThreadLocal<UserSession> local = new ThreadLocal<UserSession>();  
      
        public static void setUserSession(UserSession session) {  
            local.set(session);  
        }  
      
        public static UserSession getUserSession() {  
            return local.get();  
        }  
    }
    


    创建一个监听器,并在web.xml中配置,监听HttpSession的属性变化:
    public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {  
        public void attributeAdded(HttpSessionBindingEvent event) {  
            if ("UserSession".equals(event.getName())) {  
                SystemSession.setUserSession((UserSession)event.getValue());  
            }  
        }  
      
        public void attributeReplaced(HttpSessionBindingEvent event) {  
            if ("UserSession".equals(event.getName())) {  
                SystemSession.setUserSession((UserSession)event.getValue());  
            }  
        }  
    }
    


    用户在登录后UserSession对象会放入HttpSession中,触发监听器中的attributeAdded方法,于是UserSession对象同时也会放入ThreadLocal中,登录后每次请求会重新设置UserSession对象,触发监听器的attributeReplaced方法,UserSession对象也会放入ThreadLocal中,在程序中用以下语句即可取得UserSession对象:
    SystemSession.getUserSession();
    分享到:
    评论

    相关推荐

      正确理解ThreadLocal.pdf

      ### 正确理解ThreadLocal:深入解析其工作原理与应用场景 #### 一、ThreadLocal的基本概念 `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每...

      理解threadlocal

      ### 理解ThreadLocal #### 一、ThreadLocal简介 `ThreadLocal`是一个非常有用的类,它在Java 1.2版本中被引入到`java.lang`包中。其主要功能是在多线程环境中为每个线程提供独立的变量副本,从而避免了线程之间的...

      彻底理解ThreadLocal 1

      ThreadLocal是Java中用于线程局部变量的一个工具类,它允许在多线程环境下为每个线程创建独立的变量副本,从而避免了线程之间的数据...理解ThreadLocal的工作原理和使用方法,对于编写高效、安全的并发程序至关重要。

      正确理解ThreadLocal

      **标题:“正确理解ThreadLocal”** ThreadLocal是Java并发编程中的一个重要工具类,它提供了一种线程局部变量的机制。这些变量在每个线程中都有独立的副本,互不干扰,可以用来解决多线程环境下的数据隔离问题。...

      ThreadLocal应用示例及理解

      ### 理解ThreadLocal原理 ThreadLocal内部通过一个ThreadLocalMap来存储每个线程的副本。这个Map的键是ThreadLocal实例,值是线程的局部变量。每个线程都有自己的ThreadLocalMap,存储在Thread类的成员变量中。 ##...

      深入理解ThreadLocal工作原理及使用示例

      深入理解ThreadLocal工作原理及使用示例 ThreadLocal是Java提供的一种解决多线程程序并发问题的工具类,自JDK1.2版本以来提供了java.lang.ThreadLocal类。ThreadLocal的主要作用是为每个使用该变量的线程提供独立的...

      ThreadLocal

      ### ThreadLocal核心概念详解 #### 一、ThreadLocal简介与重要性 ThreadLocal是一个非常重要的Java并发工具类,它的核心概念在于为每一个...理解ThreadLocal的工作原理对于编写高效、安全的多线程应用程序至关重要。

      java 简单的ThreadLocal示例

      Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,尤其在处理线程间数据隔离和共享时。...通过查看这些示例,你可以更深入地理解ThreadLocal的工作方式以及如何在你的代码中有效地利用它。

      ThreadLocal的简单理解.doc

      ThreadLocal 简单理解 ThreadLocal 是 Java 中的一个类,它提供了一个简单的方式来在每个线程中存储变量,并且能够确保这些变量之间不受影响。下面是对 ThreadLocal 的简单理解。 一、背景 最近有人问我 ...

      threadLocal

      1. 多线程:理解ThreadLocal的使用必须建立在对多线程的理解基础上,包括线程的创建、执行、同步机制等。 2. 并发编程:ThreadLocal是解决并发问题的一种策略,它提供了一种避免共享状态的方式,减少了锁的使用。 3....

      ThreadLocal_ThreadLocal源码分析_

      **ThreadLocal概述** ThreadLocal是Java中的一个线程局部变量类,它...通过理解ThreadLocal的原理和最佳实践,我们可以更有效地利用它来解决多线程环境下的数据隔离问题,同时也需要注意防止可能出现的内存泄漏风险。

      Java中ThreadLocal的设计与使用

      理解ThreadLocal的工作原理和使用方法对于编写高效、安全的多线程程序至关重要。 ### ThreadLocal简介 ThreadLocal并非一个线程对象,而是一个线程局部变量的容器。每个线程都有自己的ThreadLocal实例,它们各自...

      使用ThreadLocal管理“session”数据

      要深入理解ThreadLocal的工作原理,需要查看其源码。ThreadLocal内部使用了一个ThreadLocalMap,它是一个基于ThreadLocal实例作为键,值为用户存储对象的弱引用表。每个线程都有一个这样的ThreadLocalMap,保证了...

      Spring事务处理-ThreadLocal的使用

      在实际应用中,理解ThreadLocal在Spring事务处理中的作用有助于优化并发性能和解决多线程环境下的事务问题。例如,如果线程之间需要共享数据,但又不想影响其他线程,ThreadLocal就是一个理想的选择。同时,也要注意...

      Java并发编程中ThreadLocal的原理与应用分析

      其他说明:为了更好地理解ThreadLocal的工作机制,建议实际动手尝试文中提供的实例代码,同时注意不同版本JDK之间的差异可能会导致部分细节有所变化。对于追求高性能并发应用开发的技术人员而言,了解和运用...

      Android 详解ThreadLocal及InheritableThreadLocal

      ThreadLocal和InheritableThreadLocal是Java中两个非常重要的线程相关的类,它们在Android开发中也有广泛应用。...理解ThreadLocal和InheritableThreadLocal的工作原理对于编写健壮的多线程代码至关重要。

      ThreadLocal详解

      为了深入理解ThreadLocal的实现,我们可以构建一个简化的`SimpleThreadLocal`类示例,如代码清单1所示,其中包含了一个`Map`成员变量,用于存储线程及其对应的变量副本。 #### 结论 ThreadLocal作为一种独特的多...

      ThreadLocal那点事儿编程开发技术共6页.pdf

      【ThreadLocal那点事儿编程开发技术共6页.pdf】 这篇文档深入探讨了Java中的ThreadLocal类,这是一个在多线程编程中非常关键的工具。...如果你希望深入理解ThreadLocal,这份文档无疑是一个很好的学习资源。

    Global site tag (gtag.js) - Google Analytics