hibernate ThreadLocal

  代码

  1. package com.pb.hibernate.util;  
  2. import org.hibernate.HibernateException;  
  3. import org.hibernate.Session;  
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.cfg.Configuration;  
  6. import org.infinispan.util.logging.Log;  
  7. import org.infinispan.util.logging.LogFactory;  
  8. import org.logicalcobwebs.logging.impl.Log4jFactory;  
  9. import org.slf4j.Logger;  
  10.   
  11. /** Hibernate工具类 */  
  12. public class HibernateUtil {  
  13.     /** 日志 */  
  14.     private static final Log LOG=LogFactory.getLog(HibernateUtil.class);  
  15.     /** 线程本地变量*/  
  16.     private static final ThreadLocal MAP = new ThreadLocal();  
  17.     /** 会话工厂 */  
  18.     private static final SessionFactory SESSION_FACTORY;  
  19.          private HibernateUtil() {  
  20.     }  
  21.     static {  
  22.         try {  
  23.             LOG.debug("HibernateUtil.static - loading config");  
  24.             SESSION_FACTORY = new Configuration().configure()  
  25.                     .buildSessionFactory();  
  26.             LOG.debug("HibernateUtil.static - end");  
  27.         } catch (HibernateException e) {  
  28.             throw new RuntimeException("建立会话工厂错误" + e.getMessage(), e);  
  29.         }  
  30.     }  
  31.   
  32.     /** 
  33.      * 获得一个会话从当前的线程变量,当这个任务完成后,用户必须返回会话关闭方法 
  34.      */  
  35.     public static  Session currentSession()throws HibernateException{  
  36.         Session session=(Session)MAP.get();  
  37.         //如果会话还没有,就打开会话  
  38.     if(session==null){  
  39.         session=SESSION_FACTORY.openSession();  
  40.         //给线程变量赋值  
  41.         MAP.set(session);  
  42.     }  
  43.     return session;  
  44.     }  
  45.     /** 
  46.      * 关闭会话 
  47.      */  
  48.     public static void closeSession(){  
  49.         Session session=(Session)MAP.get();  
  50.         MAP.set(null);  
  51.         if(session!=null){  
  52.             session.close();  
  53.         }  
  54.     }  
  55. }
  56. ********************************************************************************
  57.   
  58.     解释:

     通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。

        从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
        ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
       概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

      

原文地址:https://www.cnblogs.com/ainiaiwo/p/5826769.html