`
gotothework
  • 浏览: 82741 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
最近访客 更多访客>>
社区版块
存档分类
最新评论

使用ThreadLocal管理Session

阅读更多
在利用Hibernate开发DAO模块时,我们和Session打的交道最多,所以如何合理的管理Session,避免Session的频繁创建和销毁,对于提高系统的性能来说是非常重要的,以往是通过eclipse的插件来自动完成这些代码的,当然效果是不错的,但是总是觉得不爽(没有读懂那些冗长的代码),所以现在打算自己实现Session管理的代码。

         我们知道Session是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,多个并发的线程可以同时访问一个SessionFactory并从中获取Session实例,那么Session是否是线程安全的呢?很遗憾,答案是否定的。Session中包含了数据库操作相关的状态信息,那么说如果多个线程同时使用一个Session实例进行CRUD,就很有可能导致数据存取的混乱,你能够想像那些你根本不能预测执行顺序的线程对你的一条记录进行操作的情形吗?

         在Session的众多管理方案中,我们今天来认识一种名ThreadLocal模式的解决方案。
                                                                                                                                                                                                                                                        
         早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread  local  variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。

         ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):

   public  class  ThreadLocal  {
           private  Map  values  =  Collections.synchronizedMap(new  HashMap());
           public  Object  get()  {
                Thread  currentThread  =  Thread.currentThread(); 
                      Object  result  =  values.get(currentThread); 
                        if(result  ==  null&&!values.containsKey(currentThread))  {
                             result  =  initialValue();
                             values.put(currentThread,  result); 
                        }
                        return  result; 
           }
           public  void  set(Object  newValue)  {
                values.put(Thread.currentThread(),  newValue);
           }
        public  Object  initialValue()  {
                return  null; 
           }
   } 


  
         那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册的示例之中,提供了一个通过ThreadLocal维护Session的好榜样:     
public  class  HibernateUtil  {
               public  static  final  SessionFactory  sessionFactory;
                         static  {
                                     try  {
                                               sessionFactory  =  new  Configuration().configure()
                                                                   .buildSessionFactory();
                                     }  catch  (Throwable  ex)  {
                                               throw  new  ExceptionInInitializerError(ex);
                         }
               }
               public  static  final  ThreadLocal<Session>  session  = 
                                                               new  ThreadLocal<Session>();

               public  static  Session  currentSession()  throws  HibernateException  {
                           Session  s  =  session.get();
                           if(s  ==  null)  {
                                       s  =  sessionFactory.openSession();
                                       session.set(s);
                           }
                           return  s;
               }
               public  static  void  closeSession()  throws  HibernateException  {
                           Session  s  =  session.get();
                           if(s  !=  null)  {
                                       s.close();
                           }
                           session.set(null);
               }
     }
         只要借助上面的工具类获取Session实例,我们就可以实现线程范围内的Session共享,从而避免了线程中频繁的创建和销毁Session实例。当然,不要忘记在用完后关闭Session。写到这里,想再多说一些,也许大多数时候我们的DAO并不会涉及到多线程的情形,比如我们不会将DAO的代码写在Servlet之中,那样不是良好的设计,我自己通常会在service层的代码里访问DAO的方法。但是我还是建议采用以上的工具类来管理Session,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!
分享到:
评论

相关推荐

    使用ThreadLocal管理“session”数据

    2. **为什么使用ThreadLocal管理Session?** 在传统的多线程Web应用中,由于多个线程可能会处理同一个请求,如果直接在全局变量中存储session信息,可能会导致线程安全问题。而ThreadLocal提供了一个线程局部的存储...

    Hibernager_Session_Manager_ThreadLocal

    标题“Hibernage_Session_Manager_ThreadLocal”涉及到的是Hibernate框架中的一种优化策略——使用ThreadLocal管理Session。在Java Web开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它帮助开发者将...

    通向架构师的道路(第七天)之漫谈使用ThreadLocal改进你的层次的划分

    ThreadLocal自JDK 1.2起就存在,它不是一个线程,而是一种管理线程局部变量的机制。每个线程都有其独立的ThreadLocal变量副本,这样每个线程都可以独立地修改自己的副本而不影响其他线程。这有助于避免并发问题,...

    ThreadLocal的几种误区

    ThreadLocal是Java编程中一种非常特殊的变量类型,它主要用于在多线程环境下为每个线程提供独立的变量副本,从而避免了线程间的数据共享和...因此,在使用ThreadLocal时,需要充分考虑其生命周期管理和线程安全问题。

    java中ThreadLocal类的使用

    2. **请求上下文**:在Web应用中,可以使用`ThreadLocal`保存HttpServletRequest或Session对象,方便在同一个请求处理链路中访问。 3. **线程状态**:记录线程执行过程中的状态,例如事务管理、计数器等。 然而,...

    JAVA ThreadLocal类深入

    Hibernate框架在处理数据库操作时,使用ThreadLocal来管理Session,确保每个线程都有自己独立的Session对象。这样,即使多个线程并发执行,每个线程也不会干扰其他线程的Session,避免了数据错乱的问题。例如,...

    Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    使用ThreadLocal模式管理Session,可以实现线程间的隔离,确保每个线程都有自己的独立Session,从而提高系统的并发性能和数据一致性。同时,由于SessionFactory的线程安全性,我们可以放心地在多个线程中创建和关闭...

    hibernate中session的管理

    然而,由于Session不是线程安全的,所以在多线程环境中管理Session就需要特别注意。本篇文章将详细探讨Hibernate中Session的管理,特别是如何利用ThreadLocal解决并发问题。 首先,SessionFactory是Hibernate的核心...

    正确理解ThreadLocal.pdf

    1. **数据库连接管理**:如上文的Hibernate示例,通过`ThreadLocal`管理每个线程的数据库连接,确保每个线程拥有独立的连接资源,避免了资源竞争。 2. **事务处理**:在事务管理中,`ThreadLocal`可以用于维护每个...

    ThreadLocal的用处

    - 请求上下文:在Web应用中,可以使用ThreadLocal存储HttpServletRequest、Session等与请求相关的数据,确保这些数据只在当前请求的线程内可见。 - 数据库连接:在数据库连接池中,可以使用ThreadLocal为每个线程...

    入研究java.lang.ThreadLocal类.docx

    - 使用 `ThreadLocal&lt;Session&gt;` 确保每个线程都有独立的 Session 实例。 - 通过 `initialValue()` 方法初始化每个线程的 Session。 - `currentSession()` 方法确保每次调用都能获取到当前线程的 Session 实例。 ###...

    ThreadLocal原理及在多层架构中的应用.pdf

    因此,ThreadLocal非常适合在多层架构中管理数据库连接、用户认证信息等需要线程安全但又不宜在多线程间共享的资源。 数据库连接是一个经典的例子。在没有使用连接池的原始JDBC方式中,每次通过DriverManager.get...

    Java源码解析ThreadLocal及使用场景

    ThreadLocal的使用方式非常灵活,可以用来解决各种问题,例如在Web开发中,可以使用ThreadLocal来存储用户的Session信息,在分布式系统中,可以使用ThreadLocal来存储事务id等。 ThreadLocal的实现原理是基于...

    day36 11-Hibernate中的事务:当前线程中的session

    使用ThreadLocal Session的一个关键好处是事务的自动管理。当开启一个新的Session时,Hibernate会隐式地开始一个事务;当Session关闭时,如果之前没有遇到异常,那么事务就会被提交;如果有异常,事务会被回滚,从而...

    java 中ThreadLocal 的正确用法

    * Hibernate 的 Session 管理 * 日志记录的线程关联 * 等等 ThreadLocal 的注意事项 在使用 ThreadLocal 时,我们需要注意以下几点: * ThreadLocal 变量应该是 private static 的,以避免外部访问和修改。 * 在...

    java面试题汇总

    在这个例子中,`currentSession()`方法检查当前线程的ThreadLocal变量是否有Session,如果没有,则打开新的Session并设置到ThreadLocal中,供后续代码使用。 了解这些Java多线程和ThreadLocal的基础知识对于Java...

    8个案例详解教会你ThreadLocal.docx

    例如,Spring 中的 TransactionTemplate 和 AOP 模块利用 `ThreadLocal` 存储当前事务信息,Hibernate 中的 Session 管理也依赖于 `ThreadLocal` 来保持线程绑定的 Session。 7. **线程安全** - `ThreadLocal` ...

    中小公司人事管理系统

    private static final ThreadLocal&lt;Session&gt; sessionThread=new ThreadLocal&lt;Session&gt;(); private static final ThreadLocal&lt;Transaction&gt; transactionThread=new ThreadLocal(); private static final Log log=...

    java 中ThreadLocal实例分析

    例如,在 Web 应用程序中,我们可以使用 ThreadLocal 来存储用户的 Session 信息,以便在多个请求之间共享 Session 信息。 ThreadLocal 是 Java 中的一种强大且灵活的机制,用于实现线程安全和变量隔离。它可以帮助...

Global site tag (gtag.js) - Google Analytics