专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » threadlocal:利于ThreadLocal模式管理Session »正文

threadlocal:利于ThreadLocal模式管理Session

来源: 发布时间:星期四, 2009年1月15日 浏览:43次 评论:0
  在利用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  ThreadLocal {
   private Map values = Collections.synchronizedMap( HashMap);
   public Object get {
   Thread currentThread = Thread.currentThread; 
   Object result = values.get(currentThread); 
    (result  null&&!values.containsKey(currentThread)) {
     result = initialValue;
     values.put(currentThread, result); 
      }
       result; 
     }
   public void (Object Value) {
    values.put(Thread.currentThread, Value);
    }
   public Object initialValue {
     null; 
   }
  }


  那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册举例的中提供了个通过ThreadLocal维护Session好榜样:

public  HibernateUtil {
 public  final SessionFactory sessionFactory;
   {
   try {
    sessionFactory =  Configuration.configure.buildSessionFactory;
    } catch (Throwable ex) {
     throw  ExceptionInInitializerError(ex);
      }
     }
  public final ThreadLocal<Session>session= ThreadLocal<Session>;
  public  Session currentSession throws HibernateException {
    Session s = session.get;
    (s  null) {
     s = sessionFactory.openSession;
     session.(s);
     }
      s;
     }
  public  void closeSession throws HibernateException {
     Session s = session.get;
    (s != null) {
      s.close;
     }
     session.(null);
    }
   }


  只要借助上面工具类获取Session例子我们就可以实现线程范围内Session共享从而避免了线程中频繁创建和销毁Session例子当然不要忘记在用完后关闭Session写到这里想再多说也许大多数时候我们DAO并不会涉及到多线程情形比如我们不会将DAO代码写在Servlet的中那样不是良好设计我自己通常会在service层代码里访问DAO思路方法但是我还是建议采用以上工具类来管理Session毕竟我们不能仅仅考虑今天为自己做什么还应该考虑明天为自己做什么!

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: