网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  技巧:利于threadlocal模式管理session     
  文章作者:未知  文章来源:赛迪网技术社区  
  查看:87次  录入:管理员--2007-11-16  
 

在利用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,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!

 
 
上一篇: 关于java编程的中文问题的几条分析原则    下一篇: java中数据库连接池原理机制的详细讲解
  相关文档
j2ee中用rmi和corba进行分布式java编程 03-31
struts框架基础篇 11-17
使用消息驱动beans(1) 11-17
试试jdk1.5 11-17
web 应用程序模型及其java实现之第三部分 11-17
the alloy look and feel 1.4.4破解手记 11-17
技术分析:将web站点转换为web服务二(组图) 11-17
关于创建java.exe文件的几种方法 11-17
学习struts提供的和form相关的标签 11-17
javabean的事件 11-17
java初学者要搞清 11-17
java(jvm)虚拟机结构基础 11-16
java高级:java布局管理器使用方法探讨 12-14
且看微软的.net和sun公司的j2ee如何对垒 11-16
02、《tij》目录前的部分 11-17
用tea简化web开发 11-17
ibm承诺今年年底发布代号为atlantic的开发平台 11-17
提高Java技能的几种简单有效的方法 03-25
灵活使用ejb的本地和远程接口(三) 11-17
学习jsp指南 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息