在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,因此也就不需要进行同步处理
转载于:https://blog.51cto.com/12222886/1940749