在hibernate中session是使用ThreadLocal实现线程安全的。

ThreadLocal并不是一个Thread,而是一个线程副本,ThreadLocal为每个使用该变量的线程提供一个变量副本,线程修改自己的变量副本不会影响其他线程的变量副本

ThreadLocal有四个方法:

set():设置当前线程的局部变量的值

get():获取当前线程的局部变量的值

remove():将当前线程局部变量的值删除,此方法不必显示的调用,因为局部变量自有垃圾回收器去清理

initialValue():返回该局部变量的初始值,只有在线程第一次调用get,set方法时,此方法才会执行

    ThreadLocal源码如下:

   

     
    public class ThreadLocal {
                /*这个集合中以当前线程对象作为键,值就是该线程对象的变量副本的值,也就是
                 * session
                 */
    		Map map = Collections.synchronizedMap(new HashMap());
    		public Object get(){
    			Thread currentThread = Thread.currentThread();
    			Object o = map.get(currentThread);
    			if(o == null && !map.containsKey(currentThread)){
    				o = initialValue();
    				map.put(currentThread, o);
    			}
    			return o;
    		}
    		
    		public void set(Object newValue){
    			map.put(Thread.currentThread(), newValue);
    		}
    		
    		public Object initialValue() {
    			return null;
    		}
    	}


hibernate中的getCurrentSession()的底层代码如下:

public class CurrentSession {
	
		public static final ThreadLocal session = new ThreadLocal();
		
		public static final SessionFactory sf;
		static {
			sf = new Configuration().configure().buildSessionFactory();
		}

		public Session getCurrentSession(){
			Session s = (Session) session.get();
			if(s == null){
				s = sf.openSession();
				session.set(s);
			}
			return s;
		}
	
	}

总结:要想让多线程实现对共享资源的操纵,就需要对它进行同步处理,这不是一件容易的事,不仅会降低程序性能,还要小心死锁的产生,而ThreadLocal模式,直接让每一个线程都具有自己的一个session,他仅仅操作自己的session不会影响其它线程的session,因此也就不需要进行同步处理