问题描述
可以看到,localSession是一个ThreadLocal类型的对象,在doGet方法中,我们通过其set方法将获取的session实例保存,而在doSomething方法中,通过get方法取出session实例。这也就是ThreadLocal的独特之处,它会为每个线程维护一个私有的变量空间。实际上,其实现原理是在JVM中维护一个Map,这个Map的key就是当前的线程对象,而value则是线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时,ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回。这样,ThreadLocal通过以各个线程对象的引用作为区分,从而将不同线程的变量隔离开来。回到上面的例子,通过应用ThreadLocal机制,线程A的session实例只能为线程A所用,同样,其他线程的session实例也各自从属于自己的线程。这样,我们就实现了线程安全的Session共享机制。Hibernate官方开发手册的示例中,提供了一个通过ThreadLocal维护Session的好榜样:publicclassHibernateUtil{privatestaticSessionFactorysessionFactory;static{try{//CreatetheSessionFactorysessionFactory=newConfiguration().configure().buildSessionFactory();}catch(HibernateExceptionex){thrownewRuntimeException("Configurationproblem:"+ex.getMessage(),ex);}}publicstaticfinalThreadLocalsession=newThreadLocal();publicstaticSessioncurrentSession()throwsHibernateException{Sessions=(Session)session.get();//OpenanewSession,ifthisThreadhasnoneyetif(s==null){s=sessionFactory.openSession();session.set(s);}returns;}publicstaticvoidcloseSession()throwsHibernateException{Sessions=(Session)session.get();session.set(null);if(s!=null)s.close();}}