在hibernate中session是使用ThreadLocal實現線程安全的。java
ThreadLocal並非一個Thread,而是一個線程副本,ThreadLocal爲每一個使用該變量的線程提供一個變量副本,線程修改本身的變量副本不會影響其餘線程的變量副本安全
ThreadLocal有四個方法:session
set():設置當前線程的局部變量的值多線程
get():獲取當前線程的局部變量的值ide
remove():將當前線程局部變量的值刪除,此方法沒必要顯示的調用,由於局部變量自有垃圾回收器去清理性能
initialValue():返回該局部變量的初始值,只有在線程第一次調用get,set方法時,此方法纔會執行ui
ThreadLocal源碼以下:
spa
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()的底層代碼以下:hibernate
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,所以也就不須要進行同步處理線程